/* * Synchronization for bounded-buffer problem, using locks and * condition variables to simulate monitors. */ #include #include "bbuffer.h" /* global variables */ pthread_mutex_t monitor_mutex; pthread_cond_t not_empty; pthread_cond_t not_full; /* function definitions */ void init_synch(void) { pthread_mutex_init(&monitor_mutex, NULL); pthread_cond_init(¬_empty, NULL); pthread_cond_init(¬_full, NULL); } void cleanup_synch(void) { pthread_mutex_destroy(&monitor_mutex); pthread_cond_destroy(¬_empty); pthread_cond_destroy(¬_full); } void put_with_synch(const int producerID, const bbuffer_item_t item, bbuffer_t * buffer) { pthread_mutex_lock(&monitor_mutex); /* * "while" not "if" because POSIX implementation of condition * variables sometimes generates spurious signals. */ while (buffer->count == buffer->size) { pthread_cond_wait(¬_full, &monitor_mutex); } bbuffer_insert(buffer, item); printf("at time %ld producer %d added item, count now %d\n", elapsed_time(), producerID, buffer->count); pthread_cond_signal(¬_empty); pthread_mutex_unlock(&monitor_mutex); } bbuffer_item_t get_with_synch(const int consumerID, bbuffer_t * buffer) { pthread_mutex_lock(&monitor_mutex); /* * "while" not "if" because POSIX implementation of condition * variables sometimes generates spurious signals. */ while (buffer->count == 0) { pthread_cond_wait(¬_empty, &monitor_mutex); } bbuffer_item_t item = bbuffer_remove(buffer); printf("at time %ld consumer %d removed item, count now %d\n", elapsed_time(), consumerID, buffer->count); pthread_cond_signal(¬_full); pthread_mutex_unlock(&monitor_mutex); return item; }