[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#503162: marked as done (libc6: Doubt with nptl)



Your message dated Thu, 23 Oct 2008 12:09:50 +0200
with message-id <20081023100950.GD28553@hall.aurel32.net>
and subject line Re: Bug#503162: libc6: Doubt with nptl
has caused the Debian Bug report #503162,
regarding libc6: Doubt with nptl
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
503162: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=503162
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: libc6
Version: 2.7-15
Severity: normal

*** Please type your report below this line ***

Hello! At first I want to say that I'm not sure that debian
tracking system is a right place for my question and I
apologize if it really is not. I already sent it to the
gcc-help mailing list but got no response.

I have problems using the pthread_rwlock. It means that
it's broken or I have some global misunderstanding of
the read-write lock idea. The attached program simply
uses the main functionality of the pthread_rwlock: there
is an integer variable which can be accessed simultaneously.
Every time you type a command ("r" or "w X", where X is an
integer value) a new thread is being launched. It locks the
variable for 5 seconds and executes your query. The problem
is: if you type "r w 10 r" you'll get "0 0" instead of "0 10".
But if you wait for some time and type "r" again you'll get "10".
I means that the second "r" query acquired the read lock while
the "w" query was blocked. It contradicts the statement you
can see in the "pthread_rwlock_rdlock" manual:
"The calling thread acquires the read lock if a writer does
not hold the lock and there are no writers blocked on the lock."

The program can be compiled with
"gcc main.c -o main -std=gnu99 -l pthread"

Alexey Salmin

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.26-1-amd64 (SMP w/1 CPU core)
Locale: LANG=ru_RU.KOI8-R, LC_CTYPE=ru_RU.KOI8-R (charmap=KOI8-R)
(ignored: LC_ALL set to ru_RU.KOI8-R)
Shell: /bin/sh linked to /bin/bash

Versions of packages libc6 depends on:
ii  libgcc1                       1:4.3.2-1  GCC support library

libc6 recommends no packages.

Versions of packages libc6 suggests:
pn  glibc-doc                     <none>     (no description available)
ii  locales                       2.7-15     GNU C Library: National Language (

-- debconf information excluded
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sched.h>


extern char *strerror(int errnum);

/* An integer variable protected with rwlock. */
typedef struct data_t_ {
	int a;
	pthread_rwlock_t *restrict rwlock;
} data_t;

typedef enum query_type_t_ {
	Q_READ,
	Q_WRITE,
} query_type_t;

/* A query passed to the thread_func. */
typedef struct query_t_ {
	query_type_t type;
	int a;	// if (type == Q_WRITE) then "a" contains value to be written
	data_t *data;	// data to be modified
} query_t;

void *thread_func(void *arg) {
	query_t *q = (query_t *)arg;
	int err;
	if (q->type == Q_READ) {
		if (err = pthread_rwlock_rdlock(q->data->rwlock)) {
			fprintf(stderr, "Can't get read lock: %s\n", strerror(err));
			free(q);
			return (void *)(-1);
		}
		printf("%d\n", q->data->a);
	} else {
		// q->type == Q_WRITE
		if (err = pthread_rwlock_wrlock(q->data->rwlock)) {
			fprintf(stderr, "Can't get write lock: %s\n", strerror(err));
			free(q);
			return (void *)(-1);
		}
		q->data->a = q->a;
	}
	sleep(5);
	free(q);
	if (err = pthread_rwlock_unlock(q->data->rwlock)) {
		fprintf(stderr, "Error during unlocking: %s\n", strerror(err));
		return (void *)(-1);
	}
	return 0;
}

int main() {
	int err;
	data_t data;
	data.a = 0;
	data.rwlock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t));
	if (err = pthread_rwlock_init(data.rwlock, 0)) {
		fprintf(stderr, "Can't initialize rwlock structure: %s\n", strerror(err));
		exit(1);
	}
	while (1) {
		char c;
		pthread_t pthread;
		pthread_attr_t pthread_attr;
		query_t *q = (query_t *)malloc(sizeof(query_t));
		q->data = &data;
		if (scanf("\n%c", &c) != 1 || c == 'q') {
			break;
		}
		if (c == 'r') {
			q->type = Q_READ;
		} else if (c == 'w') {
			int a;
			q->type = Q_WRITE;
			if (scanf("%d", &a) != 1) {
				printf("Numeric data expected\n");
				free(q);
				continue;
			}
			q->a = a;
		} else {
			printf("Unknown command: %c\n", c);
			free(q);
			continue;
		}
		if (err = pthread_attr_init(&pthread_attr)) {
			fprintf(stderr, "Can't initialize pthread_attr structure: %s\n", strerror(err));
			exit(1);	
		}
		/*if (err = pthread_attr_setschedpolicy(&pthread_attr, SCHED_OTHER)) {
			fprintf(stderr, "Can't set sched policy: %s\n", strerror(err));
			exit(1);	
		}*/
		if (err = pthread_create(&pthread, &pthread_attr, thread_func, q)) {
			fprintf(stderr, "Can't create thread: %s\n", strerror(err));
			exit(1);	
		}
	}
	return 0;
}

--- End Message ---
--- Begin Message ---
On Thu, Oct 23, 2008 at 11:56:46AM +0700, Alexey Salmin wrote:
> Package: libc6
> Version: 2.7-15
> Severity: normal
> 
> *** Please type your report below this line ***
> 
> Hello! At first I want to say that I'm not sure that debian
> tracking system is a right place for my question and I
> apologize if it really is not. I already sent it to the
> gcc-help mailing list but got no response.
> 
> I have problems using the pthread_rwlock. It means that
> it's broken or I have some global misunderstanding of
> the read-write lock idea. The attached program simply
> uses the main functionality of the pthread_rwlock: there
> is an integer variable which can be accessed simultaneously.
> Every time you type a command ("r" or "w X", where X is an
> integer value) a new thread is being launched. It locks the
> variable for 5 seconds and executes your query. The problem
> is: if you type "r w 10 r" you'll get "0 0" instead of "0 10".
> But if you wait for some time and type "r" again you'll get "10".
> I means that the second "r" query acquired the read lock while
> the "w" query was blocked. It contradicts the statement you
> can see in the "pthread_rwlock_rdlock" manual:
> "The calling thread acquires the read lock if a writer does
> not hold the lock and there are no writers blocked on the lock."
> 
> The program can be compiled with
> "gcc main.c -o main -std=gnu99 -l pthread"
> 
> Alexey Salmin
> 
> -- System Information:
> Debian Release: lenny/sid
>   APT prefers unstable
>   APT policy: (500, 'unstable'), (1, 'experimental')
> Architecture: amd64 (x86_64)
> 
> Kernel: Linux 2.6.26-1-amd64 (SMP w/1 CPU core)
> Locale: LANG=ru_RU.KOI8-R, LC_CTYPE=ru_RU.KOI8-R (charmap=KOI8-R)
> (ignored: LC_ALL set to ru_RU.KOI8-R)
> Shell: /bin/sh linked to /bin/bash
> 
> Versions of packages libc6 depends on:
> ii  libgcc1                       1:4.3.2-1  GCC support library
> 
> libc6 recommends no packages.
> 
> Versions of packages libc6 suggests:
> pn  glibc-doc                     <none>     (no description available)
> ii  locales                       2.7-15     GNU C Library: National Language (
> 
> -- debconf information excluded

> #include <stdio.h>
> #include <pthread.h>
> #include <errno.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <sched.h>
> 
> 
> extern char *strerror(int errnum);
> 
> /* An integer variable protected with rwlock. */
> typedef struct data_t_ {
> 	int a;
> 	pthread_rwlock_t *restrict rwlock;
> } data_t;
> 
> typedef enum query_type_t_ {
> 	Q_READ,
> 	Q_WRITE,
> } query_type_t;
> 
> /* A query passed to the thread_func. */
> typedef struct query_t_ {
> 	query_type_t type;
> 	int a;	// if (type == Q_WRITE) then "a" contains value to be written
> 	data_t *data;	// data to be modified
> } query_t;
> 
> void *thread_func(void *arg) {
> 	query_t *q = (query_t *)arg;
> 	int err;
> 	if (q->type == Q_READ) {
> 		if (err = pthread_rwlock_rdlock(q->data->rwlock)) {
> 			fprintf(stderr, "Can't get read lock: %s\n", strerror(err));
> 			free(q);
> 			return (void *)(-1);
> 		}
> 		printf("%d\n", q->data->a);
> 	} else {
> 		// q->type == Q_WRITE
> 		if (err = pthread_rwlock_wrlock(q->data->rwlock)) {
> 			fprintf(stderr, "Can't get write lock: %s\n", strerror(err));
> 			free(q);
> 			return (void *)(-1);
> 		}
> 		q->data->a = q->a;
> 	}
> 	sleep(5);
> 	free(q);

Freeing a variable...

> 	if (err = pthread_rwlock_unlock(q->data->rwlock)) {

...and using it later is never a good idea. This is a problem in your
program, closing the bug.

> 		fprintf(stderr, "Error during unlocking: %s\n", strerror(err));
> 		return (void *)(-1);
> 	}
> 	return 0;
> }
> 
> int main() {
> 	int err;
> 	data_t data;
> 	data.a = 0;
> 	data.rwlock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t));
> 	if (err = pthread_rwlock_init(data.rwlock, 0)) {
> 		fprintf(stderr, "Can't initialize rwlock structure: %s\n", strerror(err));
> 		exit(1);
> 	}
> 	while (1) {
> 		char c;
> 		pthread_t pthread;
> 		pthread_attr_t pthread_attr;
> 		query_t *q = (query_t *)malloc(sizeof(query_t));
> 		q->data = &data;
> 		if (scanf("\n%c", &c) != 1 || c == 'q') {
> 			break;
> 		}
> 		if (c == 'r') {
> 			q->type = Q_READ;
> 		} else if (c == 'w') {
> 			int a;
> 			q->type = Q_WRITE;
> 			if (scanf("%d", &a) != 1) {
> 				printf("Numeric data expected\n");
> 				free(q);
> 				continue;
> 			}
> 			q->a = a;
> 		} else {
> 			printf("Unknown command: %c\n", c);
> 			free(q);
> 			continue;
> 		}
> 		if (err = pthread_attr_init(&pthread_attr)) {
> 			fprintf(stderr, "Can't initialize pthread_attr structure: %s\n", strerror(err));
> 			exit(1);	
> 		}
> 		/*if (err = pthread_attr_setschedpolicy(&pthread_attr, SCHED_OTHER)) {
> 			fprintf(stderr, "Can't set sched policy: %s\n", strerror(err));
> 			exit(1);	
> 		}*/
> 		if (err = pthread_create(&pthread, &pthread_attr, thread_func, q)) {
> 			fprintf(stderr, "Can't create thread: %s\n", strerror(err));
> 			exit(1);	
> 		}
> 	}
> 	return 0;
> }


-- 
  .''`.  Aurelien Jarno	            | GPG: 1024D/F1BCDB73
 : :' :  Debian developer           | Electrical Engineer
 `. `'   aurel32@debian.org         | aurelien@aurel32.net
   `-    people.debian.org/~aurel32 | www.aurel32.net


--- End Message ---

Reply to: