Pthread Read/Write Lock Freeze one of the calling thread.

Gauthier, Simon Simon.Gauthier at verint.com
Tue Feb 9 21:04:02 UTC 2010


Hi,

I have two threads locking the same rwlock. When the second takes the lock while the first has it, the second thread deadlock forever on the lock. But the first one unlock and can still lock and unlock the rwlock. This behavior is not seen on a i386 with glibc.

I am using uclibc 0.9.29 with cross compile toolchain for ARM926EJ-S rev 5 (v5l).

Here is the ouput of the test app:

root at test:/mnt/nfs/lock# ./locktestarm
ucLibc rwlock test.
Entering worker thread [1].
The list is locked by the timer thread [1].
Entering worker thread [2].
The list is locked by the timer thread [2].
Entering main thread.
The list is unlocked by the timer thread [1].
The list is locked by the timer thread [1].
The list is unlocked by the timer thread [1].
The list is locked by the timer thread [1].
The list is unlocked by the timer thread [1].

We see both worker thread takes the lock, the second thread will then be locked forever on it.

Here is how I compile the code:

arm-linux-uclibc-gcc ./rwlock_test.c -o locktestarm -lpthread -D_GNU_SOURCE

Here is the code snippet:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <bits/pthreadtypes.h>

pthread_t worker_thread;
pthread_t test_thread;
pthread_rwlock_t *rwlock;

static unsigned int running = 1;

static void* timer_thread(void* pvContext);

int main()
{
   pthread_rwlockattr_t rwlockattr;
   int ret = 0;

   printf("ucLibc rwlock test.\n");

   rwlock = (pthread_rwlock_t*)malloc(sizeof(pthread_rwlock_t));
   if (rwlock == NULL)
   {
      printf("Failed to alloc rw memory\n");
      return -1;
   }

   ret = pthread_rwlockattr_init(&rwlockattr);
   if (ret != 0)
   {
      printf("Failed to init rwlock attr\n");
      return -1;

   }
   ret = pthread_rwlock_init(rwlock, &rwlockattr);
   if (ret != 0)
   {
      printf("Failed to int rw lock\n");
      return -1;
   }

   pthread_rwlockattr_destroy(&rwlockattr);

   ret = pthread_create(&worker_thread, NULL, &timer_thread, (void*)1);
   if(ret != 0)
   {
      printf("Failed to create timer thread\n");
      return -1;
   }

   ret = pthread_create(&test_thread, NULL, &timer_thread, (void*)2);
   if(ret != 0)
   {
      printf("Failed to create timer thread\n");
      return -1;
   }

   printf("Entering main thread.\n");

   while ( running )
   {
      sleep(1);
   }

   return 0;
}

static void* timer_thread(void* pvContext)
{
   int value = (int)pvContext;
   printf("Entering worker thread [%d].\n", value);

   while(running)
   {
      printf("The list is locked by the timer thread [%d].\n", value);

      pthread_rwlock_wrlock(rwlock);

      sleep(1);

      pthread_rwlock_unlock(rwlock);

      printf("The list is unlocked by the timer thread [%d].\n", value);
   }
}


Thanks

Simon Gauthier

This electronic message may contain proprietary and confidential information of Verint Systems Inc., its affiliates and/or subsidiaries.
The information is intended to be for the use of the individual(s) or
entity(ies) named above.  If you are not the intended recipient (or authorized to receive this e-mail for the intended recipient), you may not use, copy, disclose or distribute to anyone this message or any information contained in this message.  If you have received this electronic message in error, please notify us by replying to this e-mail.



More information about the uClibc mailing list