When creating a rwlock, ask for PTHREAD_RWLOCK_PREFER_WRITER_NP. The resulting behavior is identical to PTHREAD_RWLOCK_PREFER_READER_NP, as can be seen in the source. The following test case shows that as long as there are readers holding the lock, a writer thread will be starved forever. However, if the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP option is used, the writer thread gets to run. It is not allowed to be recursive, however. ------------------------------------------------------------- #define _XOPEN_SOURCE 600 #include <pthread.h> #include <stdio.h> #include <unistd.h> #include <assert.h> #include <time.h> #include <error.h> #include <string.h> #define NUM_THREADS (250) pthread_rwlock_t lock; void *readfunc(void *arg) { long long id = (long long)arg; while (1) { struct timespec ts = {.tv_sec = 0,.tv_nsec = (id%25 +1)*1000*1000 }; assert(0==pthread_rwlock_rdlock(&lock)); nanosleep(&ts,NULL); assert(0==pthread_rwlock_unlock(&lock)); } } void *writefunc(void *arg) { sleep(1); assert(0==pthread_rwlock_wrlock(&lock)); // assert(0==pthread_rwlock_wrlock(&lock)); //would fail if non-recursive printf("Writer got a chance!\n"); // assert(0==pthread_rwlock_unlock(&lock)); assert(0==pthread_rwlock_unlock(&lock)); return 0; } int main(int argc,char *argv[]) { pthread_t writer,readers[NUM_THREADS]; pthread_rwlockattr_t lockattr; assert(0==pthread_rwlockattr_init(&lockattr)); assert(0==pthread_rwlockattr_setkind_np(&lockattr,PTHREAD_RWLOCK_PREFER_WRITER_NP)); assert(0==pthread_rwlock_init(&lock,&lockattr)); assert(0==pthread_rwlockattr_destroy(&lockattr)); for (long long i=0;i<NUM_THREADS;i++) assert(0==pthread_create(readers+i,NULL,readfunc,(void *)i)); assert(0==pthread_create(&writer,NULL,writefunc,0)); printf("main waits\n"); pthread_join(writer,NULL); return 0; }
And there won't be any implementation.
Uli I think this question deserves a more complete explanation. This seems like a reasonable request. If you disagree then it would not hurt to explain why. There seems to be a valid concern related to reliable implementation of recursive read locks with writer priority. As in this discusion: http://sources.redhat.com/ml/libc-alpha/2000-01/msg00055.html If this your concern then saying so would help resolve/close this issue.
(In reply to Steven Munroe from comment #2) > Uli I think this question deserves a more complete explanation. > > This seems like a reasonable request. If you disagree then it would not hurt > to explain why. > > There seems to be a valid concern related to reliable implementation of > recursive read locks with writer priority. As in this discusion: > > http://sources.redhat.com/ml/libc-alpha/2000-01/msg00055.html > > If this your concern then saying so would help resolve/close this issue. I'm making a statement here that this is exactly the case. Adding support for PTHREAD_RWLOCK_PREFER_WRITER_NP is not possible without serious negative consequences. It is not a bug, it is simply a conflicting requirement between PTHREAD_RWLOCK_PREFER_WRITER_NP (a non-portable extension) and POSIX that cannot be satisfied without significant difficulty, and because of that we don't support PTHREAD_RWLOCK_PREFER_WRITER_NP (but can't get rid of it for ABI reasons), instead we have an additional constant PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP which ensures the readers are non-recursive and thus writer preference can be implemented without the obvious deadlock. I am rewriting the Linux man-pages document to state this, which was the decision made on the mailing list but was never followed up.