1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Unit test for drd that triggers a race on the use of a POSIX condition 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown variable. By Bart Van Assche. 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <assert.h> 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> // printf() 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h> 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h> // usleep() 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Local functions declarations. 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void* thread_func(void* thread_arg); 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Local variables. 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic pthread_mutex_t s_mutex; 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic pthread_cond_t s_cond; 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int s_use_mutex = 0; 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Function definitions. 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(int argc, char** argv) 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int optchar; 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_t threadid; 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ((optchar = getopt(argc, argv, "m")) != EOF) 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (optchar) 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'm': 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s_use_mutex = 1; 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assert(0); 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_cond_init(&s_cond, 0); 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_mutex_init(&s_mutex, 0); 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_mutex_lock(&s_mutex); 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create(&threadid, 0, thread_func, 0); 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_cond_wait(&s_cond, &s_mutex); 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_mutex_unlock(&s_mutex); 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_join(threadid, 0); 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_mutex_destroy(&s_mutex); 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_cond_destroy(&s_cond); 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void* thread_func(void* thread_arg) 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Wait until the main thread has entered pthread_cond_wait(). 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_mutex_lock(&s_mutex); 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_mutex_unlock(&s_mutex); 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Signal the condition variable. 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s_use_mutex) pthread_mutex_lock(&s_mutex); 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_cond_signal(&s_cond); 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s_use_mutex) pthread_mutex_unlock(&s_mutex); 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 72