/*
 * Michael Gousie
 * procon.cc
 *
 * Producer-Consumer example.
 * Uses POSIX threads and POSIX semaphores.
 * 10/09/09
 *
 */

#include <pthread.h>
#include <semaphore.h>
#include <iostream>
#include <fstream>
#include <math.h>

using namespace std;

void* produce (void*);
void* consume (void*);

sem_t S;
int numbers [20];

int main () 
{
   pthread_t thread1, thread2;

   // set up semaphores
   sem_init (&S, 0, -1);

   // set up threads
   // read text
   pthread_create (&thread2, NULL, produce, NULL);
   pthread_create (&thread1, NULL, consume, NULL);

   // finish all threads before displaying finished text
   pthread_join (thread1, NULL);
   pthread_join (thread2, NULL);

   sem_destroy (&S);

   cout << "***Done***" << endl;

   return 0;
}


void* produce (void*)
/*
 * Read input file
 * Returns text in 2D array along with number of rows.
 */
{
   int i;
   int Svalue;

   for (i = 0; i < 20; i++) {
      numbers [i] = i*10;
      sem_getvalue (&S, &Svalue);
      cout << "thread 1: " << numbers [i] << "  S value pre: " << Svalue << endl;
      sem_post (&S);
      sem_getvalue (&S, &Svalue);
      cout << "thread 1: " << numbers [i] << "  S value post: " << Svalue << endl;
      if (i < 10) sleep (1);
   }
} // produce


void* consume (void*)
{
   int i;
   int Svalue;

   for (i = 0; i < 20; i++) {
      sem_getvalue (&S, &Svalue);
      cout << "thread 2: " << numbers [i] << "  S value pre: " << Svalue << endl;
      sem_wait (&S);
      sem_getvalue (&S, &Svalue);
      cout << "thread 2: " << numbers [i] << "  S value post: " << Svalue << endl;
      //sleep (2);
   }
} // consume
