title: Forcing a thread context switch
body: <p>I would like to be able to force a context switch from one thread to another. Therefore, I have implemented the following locking procedure:</p>
  
  <pre><code>#define TRUE  (1==1)
  #define FALSE (0==1)
  
  #include &lt;pthread.h&gt;
  
  int acquire(void);
  int release(void);
  int c_yield(int count);
  
  // Who was the last to acquire the lock
  static volatile pthread_t lock_owner;
  
  // Is the lock currently taken
  static volatile int lock_taken = FALSE;
  
  /* This variable indicates how many threads are currently waiting for
   * the lock. */
  static volatile int lock_wanted = 0;
  
  /* Mutex for protecting access to lock_wanted, lock_owner and
   * lock_taken */
  static pthread_mutex_t mutex;
  
  /* Condition even to notify when the lock becomes available */
  static pthread_cond_t cond;
  
  void init_lock(void) {
      pthread_cond_init(&amp;cond, NULL);
      pthread_mutex_init(&amp;mutex, NULL);
  }
  
  int acquire(void) {
      pthread_mutex_lock(&amp;mutex);
      if(lock_taken) {
          lock_wanted++;
          pthread_cond_wait(&amp;cond, &amp;mutex);
          lock_wanted--;
      } 
      if(lock_taken) {
          pthread_mutex_unlock(&amp;mutex);
          return EPROTO;
      } 
      lock_taken = TRUE;
      lock_owner = pthread_self();
      return pthread_mutex_unlock(&amp;mutex);
  }
  
  int release(void) {
      pthread_mutex_lock(&amp;mutex);
      lock_taken = FALSE;
      if(lock_wanted &gt; 0) {
          pthread_cond_signal(&amp;cond);
      }
      return pthread_mutex_unlock(&amp;mutex);
  }
  </code></pre>
  
  <p>Using another method (not shown), I can then implement a yield() that only returns if there are either no threads waiting for the lock, or after at least one other thread had a chance to run.</p>
  
  <p>This implementation works fine most of the time, but if I stress-test it with ~50 threads  trying to acquire and release the lock in random intervals, every once in a while acquire() will return <code>EPROTO</code>, indicating that someone called <code>pthread_cond_signal</code> without setting first <code>lock_taken = FALSE</code>.</p>
  
  <p>Why is that? It seems as if the CPU sometimes doesn't see the new value of <code>lock_taken</code>, which is why I already made the variables volatile. But it's still happening...</p>