1 #ifndef _SINGLEDISH_PTHREAD_UTILS_H_
2 #define _SINGLEDISH_PTHREAD_UTILS_H_
13 #define THROW_IF(condition, msg) \
16 throw runtime_error((msg)); \
27 mutex_(PTHREAD_MUTEX_INITIALIZER) {
29 int ret = pthread_mutex_init(&mutex_, NULL);
30 THROW_IF(ret != 0,
"Mutex::Mutex() failed to initalize mutex");
34 int ret = pthread_mutex_destroy(&mutex_);
35 THROW_IF(ret != 0,
"Mutex::~Mutex() failed to destroy mutex");
39 int ret = pthread_mutex_lock(&mutex_);
40 THROW_IF(ret != 0,
"Mutex::lock() failed to lock mutex");
45 int ret = pthread_mutex_unlock(&mutex_);
46 THROW_IF(ret != 0,
"Mutex::unlock() failed to unlock mutex");
51 return pthread_mutex_trylock(&mutex_);
63 mutex_(&(mutex->mutex_)) {
64 int ret = pthread_cond_init(&cond_, NULL);
66 "PCondition::PCondition() failed to initialize pthread_cond_t");
70 int ret = pthread_cond_destroy(&cond_);
72 "PCondition::~PCondition() failed to destroy pthread_cond_t");
76 return pthread_mutex_lock(mutex_);
81 return pthread_mutex_unlock(mutex_);
86 int ret = pthread_cond_wait(&cond_, mutex_);
87 THROW_IF(ret != 0,
"PCondition::wait() failed to block pthread_cond_t");
93 int ret = pthread_cond_signal(&cond_);
94 THROW_IF(ret != 0,
"PCondition::signal() failed to release pthread_cond_t");
103 template<
class DataType, s
size_t BufferSize>
152 return more_products;
162 end_of_production_(terminator), num_product_in_buffer_(0),
163 producer_index_(0), consumer_index_(0), mutex_(),
164 consumer_condition_(&mutex_), producer_condition_(&mutex_) {
182 return mutex_.lock();
186 return mutex_.unlock();
190 return mutex_.try_lock();
194 return producer_condition_.wait();
198 return producer_condition_.signal();
202 return consumer_condition_.wait();
206 return consumer_condition_.signal();
210 return num_product_in_buffer_ >= BufferSize;
214 return num_product_in_buffer_ <= 0;
219 producer_index_ %= BufferSize;
220 num_product_in_buffer_++;
225 consumer_index_ %= BufferSize;
226 num_product_in_buffer_--;
230 buffer_[producer_index_] = item;
234 *item = buffer_[consumer_index_];
241 DataType buffer_[BufferSize];
250 void create_thread(pthread_t *tid, pthread_attr_t *attr,
void *(*func)(
void *),
static void locked_print(T msg, _Context *context)
utility
#define THROW_IF(condition, msg)
virtual ~PCondition() noexcept(false)
void create_thread(pthread_t *tid, pthread_attr_t *attr, void *(*func)(void *), void *param)
~ProducerConsumerModelContext()
destructor
static void complete_production(_Context *context)
it should be called when production complete
ProducerConsumerModelContext(DataType const terminator)
constructor
ProducerConsumerModelContext< DataType, BufferSize > _Context
DataType const end_of_production_
terminator data (product == end_of_production_) indicates that production is completed.
PCondition producer_condition_
implementation of producer consumer model
void push_product(DataType item)
PCondition consumer_condition_
static void produce(_Context *context, DataType item)
production function
static bool consume(_Context *context, DataType *item)
consumption function return false if no more products available otherwise return true ...
ssize_t num_product_in_buffer_
void pop_product(DataType *item)
void join_thread(pthread_t *tid, void **status)