X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/5fd8cc8409d0efadc07dfe8d6774ad9ff477663d..46fb2b4bbe3a0a8516ab04cfafa895a882c70f86:/rpc/fifo.h diff --git a/rpc/fifo.h b/rpc/fifo.h index 979cf62..215ec5b 100644 --- a/rpc/fifo.h +++ b/rpc/fifo.h @@ -1,94 +1,52 @@ #ifndef fifo_h #define fifo_h -// fifo template -// blocks enq() and deq() when queue is FULL or EMPTY - -#include -#include -#include -#include -#include -#include "slock.h" -#include "lang/verify.h" +#include "types.h" +// blocks enq() and deq() when queue is FULL or EMPTY template class fifo { public: - fifo(int m=0); - ~fifo(); + fifo(size_t limit=0) : max_(limit) {} bool enq(T, bool blocking=true); void deq(T *); - bool size(); + bool size() { + lock ml(m_); + return q_.size(); + } private: - std::list q_; - pthread_mutex_t m_; - pthread_cond_t non_empty_c_; // q went non-empty - pthread_cond_t has_space_c_; // q is not longer overfull - unsigned int max_; //maximum capacity of the queue, block enq threads if exceeds this limit + list q_; + mutex m_; + cond non_empty_c_; // q went non-empty + cond has_space_c_; // q is not longer overfull + size_t max_; // maximum capacity of the queue, block enq threads if exceeds this limit }; -template -fifo::fifo(int limit) : max_(limit) -{ - VERIFY(pthread_mutex_init(&m_, 0) == 0); - VERIFY(pthread_cond_init(&non_empty_c_, 0) == 0); - VERIFY(pthread_cond_init(&has_space_c_, 0) == 0); -} - -template -fifo::~fifo() -{ - //fifo is to be deleted only when no threads are using it! - VERIFY(pthread_mutex_destroy(&m_)==0); - VERIFY(pthread_cond_destroy(&non_empty_c_) == 0); - VERIFY(pthread_cond_destroy(&has_space_c_) == 0); -} - -template bool -fifo::size() -{ - ScopedLock ml(&m_); - return q_.size(); -} - template bool fifo::enq(T e, bool blocking) { - ScopedLock ml(&m_); - while (1) { - if (!max_ || q_.size() < max_) { - q_.push_back(e); - break; - } - if (blocking) - VERIFY(pthread_cond_wait(&has_space_c_, &m_) == 0); - else + lock ml(m_); + while (max_ && q_.size() >= max_) { + if (!blocking) return false; + has_space_c_.wait(ml); } - VERIFY(pthread_cond_signal(&non_empty_c_) == 0); + q_.push_back(e); + non_empty_c_.notify_one(); return true; } template void fifo::deq(T *e) { - ScopedLock ml(&m_); - - while(1) { - if(q_.empty()){ - VERIFY (pthread_cond_wait(&non_empty_c_, &m_) == 0); - } else { - *e = q_.front(); - q_.pop_front(); - if (max_ && q_.size() < max_) { - VERIFY(pthread_cond_signal(&has_space_c_)==0); - } - break; - } - } - return; + lock ml(m_); + while(q_.empty()) + non_empty_c_.wait(ml); + *e = q_.front(); + q_.pop_front(); + if (max_ && q_.size() < max_) + has_space_c_.notify_one(); } #endif