15bd9f2d42ba9440b528b1f926dd57b4652cb0583bart/** Cause a race inside code protected by a reader lock. 25bd9f2d42ba9440b528b1f926dd57b4652cb0583bart */ 35bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 45bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 55bd9f2d42ba9440b528b1f926dd57b4652cb0583bart/* Needed for older glibc's (2.3 and older, at least) who don't 65bd9f2d42ba9440b528b1f926dd57b4652cb0583bart otherwise "know" about pthread_rwlock_anything or about 75bd9f2d42ba9440b528b1f926dd57b4652cb0583bart PTHREAD_MUTEX_RECURSIVE (amongst things). */ 85bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 95bd9f2d42ba9440b528b1f926dd57b4652cb0583bart#define _GNU_SOURCE 1 105bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 115bd9f2d42ba9440b528b1f926dd57b4652cb0583bart#include <pthread.h> 1268a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart#include <stdio.h> 1368a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart#include <unistd.h> 145f57be90d2e42dff4588ea099a78c64d72ffa19ebart 155bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 165bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 175bd9f2d42ba9440b528b1f926dd57b4652cb0583bartstatic pthread_rwlock_t s_rwlock; 185bd9f2d42ba9440b528b1f926dd57b4652cb0583bartstatic int s_racy; 195bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 2068a8a20a384dcc5027e35c76fbe4f8e422dbbcdebartstatic void sleep_ms(const int ms) 2168a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart{ 2268a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart struct timespec delay = { ms / 1000, (ms % 1000) * 1000 * 1000 }; 2368a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart nanosleep(&delay, 0); 2468a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart} 2568a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart 2668a8a20a384dcc5027e35c76fbe4f8e422dbbcdebartstatic void* thread_func(void* arg) 275bd9f2d42ba9440b528b1f926dd57b4652cb0583bart{ 285bd9f2d42ba9440b528b1f926dd57b4652cb0583bart pthread_rwlock_rdlock(&s_rwlock); 295bd9f2d42ba9440b528b1f926dd57b4652cb0583bart s_racy++; 305bd9f2d42ba9440b528b1f926dd57b4652cb0583bart pthread_rwlock_unlock(&s_rwlock); 3168a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart sleep_ms(100); 325bd9f2d42ba9440b528b1f926dd57b4652cb0583bart return 0; 335bd9f2d42ba9440b528b1f926dd57b4652cb0583bart} 345bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 355bd9f2d42ba9440b528b1f926dd57b4652cb0583bartint main(int argc, char** argv) 365bd9f2d42ba9440b528b1f926dd57b4652cb0583bart{ 375bd9f2d42ba9440b528b1f926dd57b4652cb0583bart pthread_t thread1; 385bd9f2d42ba9440b528b1f926dd57b4652cb0583bart pthread_t thread2; 395bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 405bd9f2d42ba9440b528b1f926dd57b4652cb0583bart#if 0 41575ce8ef8fa86a502dabe152293320676922dcfebart 424b3a74204894e943c43cb8e8aae39d813040702csewardj VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DRD_TRACE_ADDR, 43575ce8ef8fa86a502dabe152293320676922dcfebart &s_racy, 0, 0, 0, 0); 445bd9f2d42ba9440b528b1f926dd57b4652cb0583bart#endif 455bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 465bd9f2d42ba9440b528b1f926dd57b4652cb0583bart pthread_rwlock_init(&s_rwlock, 0); 4768a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart pthread_create(&thread1, 0, thread_func, 0); 4868a8a20a384dcc5027e35c76fbe4f8e422dbbcdebart pthread_create(&thread2, 0, thread_func, 0); 495bd9f2d42ba9440b528b1f926dd57b4652cb0583bart pthread_join(thread1, 0); 505bd9f2d42ba9440b528b1f926dd57b4652cb0583bart pthread_join(thread2, 0); 515bd9f2d42ba9440b528b1f926dd57b4652cb0583bart pthread_rwlock_destroy(&s_rwlock); 525bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 535bd9f2d42ba9440b528b1f926dd57b4652cb0583bart fprintf(stderr, "Result: %d\n", s_racy); 545bd9f2d42ba9440b528b1f926dd57b4652cb0583bart 555bd9f2d42ba9440b528b1f926dd57b4652cb0583bart return 0; 565bd9f2d42ba9440b528b1f926dd57b4652cb0583bart} 57