Listing 5

#include <pthread.h>
#include <semaphore.h>

#define FIFO_CELL_T int
#define BASIC_FIFO_T int_queue
#include "fifo.h"

int_queue q;

sem_t q_count;
BOOL more_room;
pthread_cond_t more_room_cv;
pthread_mutex_t more_room_lock;

int get_data () { /* ... */ }
void process_data (int x) { /* ... */ }

void producer () {
  for (;;) {
    int x = get_data ();
    pthread_mutex_lock (& more_room_lock);
    for (;;) {
      more_room = FALSE;
      pthread_mutex_unlock (& more_room_lock);
      if (FIFO_INS_CHK (& q, x)) break;
      pthread_mutex_lock (& more_room_lock);
      while (! more_room)
        pthread_cond_wait (& more_room_cv, & more_room_lock);
    }
    sem_post (& q_count);
  }
}

void consumer () {
  for (;;) {
    sem_wait (& q_count);
    process_data (FIFO_READ (& q));
    pthread_mutex_lock (& more_room_lock);
    more_room = TRUE;
    pthread_mutex_unlock (& more_room_lock);
    pthread_cond_signal (& more_room_cv);
  }
}