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