#ifndef fifo_h
#define fifo_h
-// fifo template
-// blocks enq() and deq() when queue is FULL or EMPTY
-
-#include <errno.h>
#include <list>
-#include <sys/time.h>
-#include <time.h>
-#include <errno.h>
-#include "lang/verify.h"
#include "lock.h"
+// blocks enq() and deq() when queue is FULL or EMPTY
template<class T>
class fifo {
public:
- fifo(int m=0);
+ fifo(int 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<T> q_;
mutex m_;
- std::condition_variable non_empty_c_; // q went non-empty
- std::condition_variable has_space_c_; // q is not longer overfull
- unsigned int max_; //maximum capacity of the queue, block enq threads if exceeds this limit
+ cond non_empty_c_; // q went non-empty
+ cond has_space_c_; // q is not longer overfull
+ unsigned int max_; // maximum capacity of the queue, block enq threads if exceeds this limit
};
-template<class T>
-fifo<T>::fifo(int limit) : max_(limit)
-{
-}
-
-template<class T> bool
-fifo<T>::size()
-{
- lock ml(m_);
- return q_.size();
-}
-
template<class T> bool
fifo<T>::enq(T e, bool blocking)
{
lock ml(m_);
- while (1) {
- if (!max_ || q_.size() < max_) {
- q_.push_back(e);
- break;
- }
- if (blocking) {
- has_space_c_.wait(ml);
- }
- else
+ while (max_ && q_.size() >= max_) {
+ if (!blocking)
return false;
+ has_space_c_.wait(ml);
}
+ q_.push_back(e);
non_empty_c_.notify_one();
return true;
}
fifo<T>::deq(T *e)
{
lock ml(m_);
-
- while(1) {
- if(q_.empty()){
- non_empty_c_.wait(ml);
- } else {
- *e = q_.front();
- q_.pop_front();
- if (max_ && q_.size() < max_) {
- has_space_c_.notify_one();
- }
- break;
- }
- }
- return;
+ 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