/* * Monitor-based implementation of bounded buffer. * * Also includes "atomic increment and test" for simulation (not part of * monitor). */ #include #include #include #include #include "test-bounded-buffer.h" #include "bounded-buffer.h" /* global variables for synchronization */ pthread_mutex_t monitor_mutex; pthread_cond_t not_empty; pthread_cond_t not_full; pthread_mutex_t counter_mutex; /* to allow simulation to end gracefully */ static int buffer_size_save; static int count = 0; void init_synch(const int buffer_size) { buffer_size_save = buffer_size; pthread_mutex_init(&monitor_mutex, NULL); pthread_cond_init(¬_empty, NULL); pthread_cond_init(¬_full, NULL); pthread_mutex_init(&counter_mutex, NULL); } void end_synch(void) { pthread_mutex_destroy(&monitor_mutex); pthread_cond_destroy(¬_empty); pthread_cond_destroy(¬_full); pthread_mutex_destroy(&counter_mutex); } void simulate_put_with_synch(const int producerID) { pthread_mutex_lock(&monitor_mutex); /* * "while" not "if" because POSIX implementation of condition * variables sometimes generates spurious signals. */ while (count == buffer_size_save) { pthread_cond_wait(¬_full, &monitor_mutex); } count += 1; simulate_put(producerID); pthread_cond_signal(¬_empty); pthread_mutex_unlock(&monitor_mutex); } void simulate_get_with_synch(const int consumerID) { pthread_mutex_lock(&monitor_mutex); /* * "while" not "if" because POSIX implementation of condition * variables sometimes generates spurious signals. */ while (count == 0) { pthread_cond_wait(¬_empty, &monitor_mutex); } count -= 1; simulate_get(consumerID); pthread_cond_signal(¬_full); pthread_mutex_unlock(&monitor_mutex); } bool atomic_increment(int * value, const int limit) { pthread_mutex_lock(&counter_mutex); bool rval = (*value < limit); if (rval) { *value += 1; } pthread_mutex_unlock(&counter_mutex); return rval; }