This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

pthread_rwlock problem


Hello!
I'm not quite sure this mail was sent to a proper place but anyway I
hope I'll get some help :)
Trying to understand the way NPTL works I wrote a simple program which
uses the base
pthread_rwlock functionality (see the attached file). But it doesn't
work and I have no idea why.
My program contains an integer variable protected with pthread_rwlock.
It can execute two
simple command: "r" and "w NNN", where NNN is an integer value. When
you type 'r' symbol
to it's stdin pthread_rwlock_rdlock is being hold for 5 seconds and
stored value is being
written to the stdout. "w" command holds pthread_rwlock_wrlock for 5
second and changes
the data. Here's the text from the pthread_rwlock_rdlock manual :"The
pthread_rwlock_rdlock()
function shall apply a read lock to the read-write lock referenced by
rwlock. The calling thread
acquires the read lock if a writer does not hold the lock and (!)
there are no writers blocked on the lock (!)."
So the expected result for the "r w 10 r" command string is "0 10".
But actually it is "0 0".
It means that the second "r" command get the lock while the "w"
operation is being blocked.

I compile my program this way: "gcc main.c -o main -l pthread -std=gnu99"

My system info:
salmin@salmin:~$ uname -a
Linux salmin 2.6.26-1-amd64 #1 SMP Wed Sep 24 13:59:41 UTC 2008 x86_64 GNU/Linux
ii  gcc                       4:4.3.2-2                 The GNU C compiler
ii  libc6                     2.7-15                    GNU C Library:
Shared libraries

PS Sorry for my language :)

Alexey
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sched.h>

extern char *strerror(int errnum);

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;

typedef struct query_t_ {
	query_type_t type;
	int a;	// if type == Q_WRITE contains data to be written
	data_t *data;
} 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_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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]