#include "thread.c"

/* what are we doing */
char *things = "wakes ups";			
/* how many have we done */
unsigned long things_done=0;

/* threads */
pthread_t thread_id;
void *thread(void*);

/* globals */
unsigned long *data_accessed = &things_done;

typedef struct condition_struct {
  pthread_mutex_t mutex;
  pthread_cond_t empty;
  pthread_cond_t full;
  unsigned long value;
} condition_t;

condition_t condition = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};

/* clear a 'queue' */
void *thread(void *arg) {
  while (1) {
    pthread_mutex_lock( &condition.mutex );
    while ( condition.value == 0 )
      pthread_cond_wait( &condition.full, &condition.mutex );
    (*data_accessed)++;
    condition.value = 0;
#ifdef DEBUG
    printf("EMPTIED!");
#endif
    pthread_cond_signal( &condition.empty );
    
    pthread_mutex_unlock( &condition.mutex );
  }
}

void do_test(void) {
  pthread_t threads[10];
  int i = 0;

  /* have 10 workers */
  for ( ; i < 10 ; i++ ) 
    pthread_create( &threads[i], NULL, thread, (void*)NULL );


  /* fill a queue, signal to threads to empty it */
  while ( 1 ) {

    pthread_mutex_lock( &condition.mutex );
    /* if the queue is full, signal for worker to clean it */
    if ( condition.value ) {
      pthread_cond_signal( &condition.full );
      pthread_cond_wait( &condition.empty , &condition.mutex);
    }
    pthread_mutex_unlock( &condition.mutex );
    
    /* fill it back up */
    pthread_mutex_lock( &condition.mutex );
#ifdef DEBUG
    printf("FILLED\n");
#endif
    condition.value = 1; 
    pthread_mutex_unlock( &condition.mutex );

  }    
    
}

