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