/* 
 * 
 */

#include "main.h"
#include <pthread.h>

/*
 * Consumer.
 * 
 * Birth function for thread that performs the consumer behavior
 * 
 *Here's the protocol: 
 * Reads a production from the shared Q. 
 *   If empty, yields and tries again.
 * When has a production from every producer, broadcasts next iter to producers
 * When has all the tuples, end
 */
void* 
consumer_birthFn( void* _params )
 {
   int numProducts;
   void *production; //dummy ptr
   
   ConsumerParams* params = (ConsumerParams *)_params;
       
   
   /*The consumer does two loops.  
    * The outside loop counts the number of tuples created.
    * The inside loop collects the products for one tuple.
    * 
    *Protocol:
    * increment tupleIter
    * wake producers for next tuple
    * Reads a production from the shared Q. 
    *   If empty, yields and tries again.
    * if more productions in tuple, repeat
    * if have more tuples, repeat
    * end thread
    */
   while( tupleIter < params->numTuplesToCreate )
    {
      if( tupleIter % 1000 == 0 ) DEBUG__printf1("tuples produced: %d\n", tupleIter);
       
      // wake producers for next iter
      DEBUG__printf("consumer broadcast for next iter\n");
      pthread_mutex_lock(&tupleIterLock);
      tupleIter += 1; // increment tupleIter (global shared)
      pthread_cond_broadcast( &tupleIterCond );
      pthread_mutex_unlock(&tupleIterLock);
         
      for( numProducts = 0; numProducts < params->numProducers; numProducts++ )
       { 
         // read a production from the shared Q.
         production = NULL;
         while( production == NULL )
          { pthread_mutex_lock( &queueAccessLock );
            production = readPrivQ( commQ );
            pthread_mutex_unlock( &queueAccessLock );
            // If empty, yields and tries again.
            if( production == NULL) sched_yield();
          }
         DEBUG__printf1( "consumer got production %d\n", currProductionNum );
       } //if more productions for current tuple, repeat
    
      // have all productions for current tuple, so add tuple to output
      //add tuple to output and malloc new tuple array -- overhead meas, do nothing
      
    } // if have all tuples are going to produce, end

   //Shutdown consumer thread
   pthread_exit(NULL);
    
 }

