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