Dana Vrajitoru
B424 Parallel and Distributed Programming

Condition Variables

Variables that can be used to wait for a condition to become true and to signal another thread when the condition has been satisfied.

Declaration and initialization:

pthread_cond_t condition;
pthread_cond_init(&condition, NULL);

They are always used in conjunction with a mutex variable. A thread can wait for something to happen by calling pthread_cond_wait, and it must explicitly lock the mutex before and unlock it afterwards

Using Condition Variables

pthread_mutex_t mutex;
pthread_mutex_lock(&mutex);
pthread_cond_wait(&condition, &mutex);
pthread_unlock(&mutex);

The condition is actually satisfied by another thread that can unblock the first one by calling the pthread_cond_signal:

pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
pthread_unlock(&mutex);

If there is more than one thread waiting, the pthread_cond_wait must be replaced by pthread_cond_broadcast.

Condition Wait

pthread_cond_wait(condition, mutex) {
  cond.waiting++;
  while (true) {
    if (condition.signal>0) {
      cond.waiting--;
      cond.signal--;
      unlock(&mutex);
      lock(&mutex);
      return;
    }
    else {
      unlock(&mutex);
      wait();
      lock(&mutex);
    }
  }
}

Condition Signal and Broadcast

pthread_cond_signal(condition) {
  if (condition.waiting>condition.signal)
    condition.signal += 1;
}

pthread_cond_broadcast(condition) {
  if (condition.waiting>signal)
    condition.signal = condition.waiting;
}

Conditional Critical Section

Thread() {
  pthread_mutex_lock(&mutex);
  while(!test_condition(...))
    pthread_cond_wait(&condvar, &mutex);
  do_stuff(...); pthread_cond_signal(&condvar);
  pthread_mutex_unlock(&mutex);
}

Example: the Barrier

void Barrier(int thread_nr) {
  static int count = 0;
  pthread_mutex_lock(&mutex);
  count++;
  if (count == thread_nr) {
    pthread_cond_broadcast(&cond);
    count = 0;
  }
  else
    pthread_cond_wait(&cond, &mutex);
  pthread_mutex_unlock(&mutex);
}

Barriers

A new feature in the 1003.1j-2000 standard.

pthread_barrier_t barrier;
pthread_barrier_init(&barrier, NULL, nr_threads);
pthread_barrier_wait(&barrier);