00001
00023 #ifndef GALOIS_WORKLIST_FIFO_H
00024 #define GALOIS_WORKLIST_FIFO_H
00025
00026 #include "Galois/Runtime/ll/PaddedLock.h"
00027 #include "WLCompileCheck.h"
00028 #include <deque>
00029
00030 namespace Galois {
00031 namespace WorkList {
00032
00034 template<typename T = int, bool Concurrent = true>
00035 struct FIFO : private boost::noncopyable, private Runtime::LL::PaddedLock<Concurrent> {
00036 template<bool _concurrent>
00037 struct rethread { typedef FIFO<T, _concurrent> type; };
00038
00039 template<typename _T>
00040 struct retype { typedef FIFO<_T, Concurrent> type; };
00041
00042 private:
00043 std::deque<T> wl;
00044
00045 using Runtime::LL::PaddedLock<Concurrent>::lock;
00046 using Runtime::LL::PaddedLock<Concurrent>::try_lock;
00047 using Runtime::LL::PaddedLock<Concurrent>::unlock;
00048
00049 public:
00050 typedef T value_type;
00051
00052 void push(const value_type& val) {
00053 lock();
00054 wl.push_back(val);
00055 unlock();
00056 }
00057
00058 template<typename Iter>
00059 void push(Iter b, Iter e) {
00060 lock();
00061 wl.insert(wl.end(),b,e);
00062 unlock();
00063 }
00064
00065 template<typename RangeTy>
00066 void push_initial(const RangeTy& range) {
00067 if (Runtime::LL::getTID() == 0)
00068 push(range.begin(), range.end());
00069 }
00070
00071 void steal(FIFO& victim) {
00072 if (!Runtime::LL::TryLockPairOrdered(*this, victim))
00073 return;
00074 typename std::deque<T>::iterator split = split_range(victim.wl.begin(), wl.victim.end());
00075 wl.insert(wl.end(), victim.wl.begin(), split);
00076 victim.wl.erase(victim.wl.begin(), split);
00077 UnLockPairOrdered(*this, victim);
00078 }
00079
00080 Galois::optional<value_type> pop() {
00081 Galois::optional<value_type> retval;
00082 lock();
00083 if (!wl.empty()) {
00084 retval = wl.front();
00085 wl.pop_front();
00086 }
00087 unlock();
00088 return retval;
00089 }
00090 };
00091 GALOIS_WLCOMPILECHECK(FIFO)
00092
00093
00094 }
00095 }
00096
00097 #endif