/* Copyright (C) 2008 by Mattia Monga <mattia.monga@unimi.it> */
/* $Id$ */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

void b_insert(char*);
void b_remove(char**);


void* producer(void* args)
{ 
  while (1){
    char* o = (char*)malloc(sizeof(char));
    printf("Ho prodotto %x\n", o);
    b_insert(o);
  }
  return NULL;
}

void* consumer(void* args)
{ 
  while (1){
    char* o;
    b_remove(&o);
    free(o);
    printf("Ho consumato %x\n", o);
  }
  return NULL;
}

int main(void){
  
  pthread_t p, c;
  
  
  pthread_create(&p, NULL, &producer, NULL);
  pthread_create(&c, NULL, &consumer, NULL);
  
  pthread_join(p, NULL);
  pthread_join(c, NULL);
  return 0;
}

#define N 10
char* buffer[N];
int count = 0;

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t full = PTHREAD_COND_INITIALIZER;
pthread_cond_t empty = PTHREAD_COND_INITIALIZER;

void b_insert(char* o)
{
  pthread_mutex_lock(&lock);

  while (count == N) pthread_cond_wait(&full, &lock);
  buffer[count++] = o;
  if (count == 1) pthread_cond_signal(&empty);

  pthread_mutex_unlock(&lock);
}

/* passaggio per indirizzo per evitare di fare la return fuori dai lock */
void b_remove(char** result)
{
  pthread_mutex_lock(&lock);

  while (count == 0) pthread_cond_wait(&empty, &lock);
  *result = buffer[--count];
  if (count == N-1) pthread_cond_signal(&full);

  pthread_mutex_unlock(&lock);
}


/* Local Variables: */
/* compile-command: "make -k " */
/* End: */


