previous | start | next

Semaphores and the Buffer Operations

    1   /* $begin sbufc */
    2   #include "csapp.h"
    3   #include "sbuf.h"
    4   
    5   /* Create an empty, bounded, shared FIFO buffer with n slots */
    6   /* $begin sbuf_init */
    7   void sbuf_init(sbuf_t *sp, int n)
    8   {
    9       sp->buf = Calloc(n, sizeof(int)); 
   10       sp->n = n;                       /* Buffer holds max of n items */
   11       sp->front = sp->rear = 0;        /* Empty buffer iff front == rear */
   12       Sem_init(&sp->mutex, 0, 1);      /* Binary semaphore for locking */
   13       Sem_init(&sp->slots, 0, n);      /* Initially, buf has n empty slots */
   14       Sem_init(&sp->items, 0, 0);      /* Initially, buf has zero data items */
   15   }
   16   /* $end sbuf_init */
   17   
   18   /* Clean up buffer sp */
   19   /* $begin sbuf_deinit */
   20   void sbuf_deinit(sbuf_t *sp)
   21   {
   22       Free(sp->buf);
   23   }
   24   /* $end sbuf_deinit */
   25   
   26   /* Insert item onto the rear of shared buffer sp */
   27   /* $begin sbuf_insert */
   28   void sbuf_insert(sbuf_t *sp, int item)
   29   {
   30       P(&sp->slots);                          /* Wait for available slot */
   31       P(&sp->mutex);                          /* Lock the buffer */
   32       sp->buf[(++sp->rear)%(sp->n)] = item;   /* Insert the item */
   33       V(&sp->mutex);                          /* Unlock the buffer */
   34       V(&sp->items);                          /* Announce available item */
   35   }
   36   /* $end sbuf_insert */
   37   
   38   /* Remove and return the first item from buffer sp */
   39   /* $begin sbuf_remove */
   40   int sbuf_remove(sbuf_t *sp)
   41   {
   42       int item;
   43       P(&sp->items);                          /* Wait for available item */
   44       P(&sp->mutex);                          /* Lock the buffer */
   45       item = sp->buf[(++sp->front)%(sp->n)];  /* Remove the item */
   46       V(&sp->mutex);                          /* Unlock the buffer */
   47       V(&sp->slots);                          /* Announce available slot */
   48       return item;
   49   }
   50   /* $end sbuf_remove */
   51   /* $end sbufc */
   52   


previous | start | next