title: phread_cond_broadcast race condition
body: <p>I can't find a way to stop this race condition. The main thread calls the broadcast routine to wake up all the threads then calls a cond_wait to wait for all the threads to finish.  The last thread to finish signals the main thread.  The problem is sometimes not all the worker threads are waiting on the condition variable when the main thread does the broadcast. The code is a little messy because I was trying various fixes.</p>
  
  <pre><code>    unsigned nProcs, curProc;
      pthread_mutex_t WORKlock = PTHREAD_MUTEX_INITIALIZER;
      pthread_mutex_t MAINlock = PTHREAD_MUTEX_INITIALIZER;
      pthread_mute_t wj_varlock = PTHREAD_MUTEX_INITIALIZER;
      pthread_cond_t WORKsig = PTHREAD_COND_INITIALIZER;
      pthread_cond_t MAINsig = PTHREAD_COND_INITIALIZER;
  
      void *do_work(void *t)
      {
      static unsigned offset = 0;
      unsigned myoff = offset++, locked = 0;
      volatile int nc;
  
      while(1)
              {
              if(locked == 0)
                      pthread_mutex_lock(&amp;WORKlock);
              else
                      locked = 0;
              pthread_cond_wait(&amp;WORKsig, &amp;WORKlock);
              pthread_mutex_unlock(&amp;WORKlock);
              // this is where the work gets done
              //sleep(1);
              printf("thread %d done!\n", myoff);
  
              pthread_mutex_lock(&amp;wj_varlock);
              nc = --curProc;
              pthread_mutex_unlock(&amp;wj_varlock);
              if(nc == 0)
                      {
                      pthread_mutex_lock(&amp;WORKlock);
                      locked = 1;
                      pthread_cond_signal(&amp;MAINsig);
                      }
  
              }
       }
  
      void main(int argc, char **argv)
      {
      unsigned i, k;
      pthread_t pth;
  
      nProcs = get_nprocs();  // get number of core from system
      for(i = 0; i &lt; nProcs; ++i)
              {
              k = pthread_create(&amp;pth, NULL, do_work, NULL);
              if(k != 0)
                      {
                      perror("pthread_create");
                      exit(k);
                      }
              }
  
      pthread_mutex_lock(&amp;MAINlock);
      while(1)
              {
              //prepare work to be done
  
              puts("work prep");
              //sleep(1);
  
              curProc = nProcs; // use global var to track active threads
              pthread_cond_broadcast(&amp;WORKsig);
              pthread_cond_wait(&amp;MAINsig, &amp;MAINlock);
              }
      }
  </code></pre>