Bug 7057 - pthread rwlock does not implement 'writer preferred' option
Summary: pthread rwlock does not implement 'writer preferred' option
Status: RESOLVED WONTFIX
Alias: None
Product: glibc
Classification: Unclassified
Component: nptl (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-11-26 15:56 UTC by Ehood Garmiza
Modified: 2018-11-15 14:59 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ehood Garmiza 2008-11-26 15:56:26 UTC
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;
}
Comment 1 Ulrich Drepper 2008-11-26 16:10:08 UTC
And there won't be any implementation.
Comment 2 Steven Munroe 2008-11-30 17:33:47 UTC
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.
Comment 3 Carlos O'Donell 2018-11-15 14:59:22 UTC
(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.