Home | History | Annotate | Download | only in tests
      1 /** Cause a race inside code protected by a reader lock.
      2  */
      3 
      4 
      5 /* Needed for older glibc's (2.3 and older, at least) who don't
      6    otherwise "know" about pthread_rwlock_anything or about
      7    PTHREAD_MUTEX_RECURSIVE (amongst things). */
      8 
      9 #define _GNU_SOURCE 1
     10 
     11 #include <pthread.h>
     12 #include <stdio.h>
     13 #include <unistd.h>
     14 
     15 
     16 
     17 static pthread_rwlock_t s_rwlock;
     18 static int s_racy;
     19 
     20 static void sleep_ms(const int ms)
     21 {
     22   struct timespec delay = { ms / 1000, (ms % 1000) * 1000 * 1000 };
     23   nanosleep(&delay, 0);
     24 }
     25 
     26 static void* thread_func(void* arg)
     27 {
     28   pthread_rwlock_rdlock(&s_rwlock);
     29   s_racy++;
     30   pthread_rwlock_unlock(&s_rwlock);
     31   sleep_ms(100);
     32   return 0;
     33 }
     34 
     35 int main(int argc, char** argv)
     36 {
     37   pthread_t thread1;
     38   pthread_t thread2;
     39 
     40 #if 0
     41 
     42   VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_TRACE_ADDR,
     43                                   &s_racy, 0, 0, 0, 0);
     44 #endif
     45 
     46   pthread_rwlock_init(&s_rwlock, 0);
     47   pthread_create(&thread1, 0, thread_func, 0);
     48   pthread_create(&thread2, 0, thread_func, 0);
     49   pthread_join(thread1, 0);
     50   pthread_join(thread2, 0);
     51   pthread_rwlock_destroy(&s_rwlock);
     52 
     53   fprintf(stderr, "Result: %d\n", s_racy);
     54 
     55   return 0;
     56 }
     57