CS31 In-class Exercise

Producer/Consumer

Producer-Consumer Bounded Buffer Problem
In your group you are going to do the following:
  1. On paper, come up with a PSEUDOCODE solution to synchronize the actions of Producer and Consumer threads that add and remove items to a shared, fixed-capacity buffer:
    • Some number of Producer threads, each in a loop forever:
      1. produce the next item
      2. add it to the shared buffer (to one end of a circular queue)
    • Some number of Consumer threads, each in a loop forever:
      1. remove the next item from the front of the buffer
      2. consume it

    Some questions to consider:

    • are there actions that need to be made atomic (require mutually exclusive access)?
    • are there any scheduling types of synchronization necessary?
    • what synchronization primitives do you need? and how are they used (by whom and when)?
    • is any other state needed to synchronize the actions of threads?

    You may assume:

    • The following shared global buffer state has been declared:
        static char *buff;     // the buffer
        static int  N;         // total buffer capacity
        static int  size;      // current num items in the buffer
        static int  next_in;   // next insertion index in the buffer 
        static int  next_out;  // next remove index in the buffer
        static int  num_items; // number of items each tid should produce or consume
      
    • There exist functions to add and remove items to the buffer as a circular queue (add to one end, remove from the other).
        void add_to_queue(char item);
        char remove_from_queue();
      
      These functions have no synchronization, nor do they check if there is space on an add or something to remove on a remove. They just add or remove to buff in a circular fashion and update other state variables as a result of their actions.

    • Some pthread functions:
      pthread_mutex_lock(&mutex); 
      pthread_mutex_unlock(&mutex); 
      pthread_cond_wait(&mycond, &mutex); 
      pthread_cond_signal(&mycond); 
      pthread_barrier_init(&mybarrier, NULL, numtids); 
      pthread_barrier_wait(&mybarrier); 
      

  2. When you are happy with your pseudocode algorithm, let me know. If I'm with another group, talk with your neighbors and see how they're doing.