/* add to tail remove from head */
int buf[FIFO_SIZE];
int head;
int tail;

pthread_mutex_t  fifo_mutex;
pthread_cond_t   fifo_empty;
pthread_cond_t   fifo_full;

void fifo_init(void)
{
	head = tail = 0;
	pthread_mutex_init(&fifo_mutex, NULL);
	pthread_cond_init(&fifo_empty, NULL);
	pthread_cond_init(&fifo_full, NULL);
}

void put(int data)
{
	pthread_mutex_lock(&fifo_mutex);
	while((head > 0 && tail == (head-1)) || tail == (FIFO_SIZE-1)) {
		pthread_cond_wait(&fifo_full, &fifo_mutex);
	}
	tail = (tail < FIFO_SIZE-1) ? tail++ : 0;
	buf[tail] = data;
	pthread_mutex_unlock(&fifo_mutex);
	pthread_cond_signal(&fifo_empty);
}

int get(void)
{
	int data;
	pthread_mutex_lock(&fifo_mutex);
	while (head == tail) {
		pthread_cond_wait(&fifo_empty, &fifo_mutex);
	}
	if (head >= FIFO_SIZE) {
		/* -1 becauase head is incremented before it is used */
		head = -1;
	}
	data = buf[++head];
	pthread_mutex_unlock(&fifo_mutex);
	pthread_cond_signal(&fifo_full);
}
	
