00001
00023 #ifndef GALOIS_WORKLIST_OWNERCOMPUTES_H
00024 #define GALOIS_WORKLIST_OWNERCOMPUTES_H
00025
00026 #include "WLCompileCheck.h"
00027
00028 namespace Galois {
00029 namespace WorkList {
00030
00031 template<typename OwnerFn=DummyIndexer<int>, typename Container=ChunkedLIFO<>, typename T = int>
00032 struct OwnerComputes : private boost::noncopyable {
00033 template<bool _concurrent>
00034 struct rethread { typedef OwnerComputes<OwnerFn, typename Container::template rethread<_concurrent>::type, T> type; };
00035
00036 template<typename _T>
00037 struct retype { typedef OwnerComputes<OwnerFn, typename Container::template retype<_T>::type, _T> type; };
00038
00039 template<typename _container>
00040 struct with_container { typedef OwnerComputes<OwnerFn, _container, T> type; };
00041
00042 template<typename _indexer>
00043 struct with_indexer { typedef OwnerComputes<_indexer, Container, T> type; };
00044
00045 private:
00046 typedef typename Container::template retype<T>::type lWLTy;
00047
00048 typedef lWLTy cWL;
00049 typedef lWLTy pWL;
00050
00051 OwnerFn Fn;
00052 Runtime::PerPackageStorage<cWL> items;
00053 Runtime::PerPackageStorage<pWL> pushBuffer;
00054
00055 public:
00056 typedef T value_type;
00057
00058 void push(const value_type& val) {
00059 unsigned int index = Fn(val);
00060 unsigned int tid = Runtime::LL::getTID();
00061 unsigned int mindex = Runtime::LL::getPackageForThread(index);
00062
00063 if (mindex == Runtime::LL::getPackageForSelf(tid))
00064 items.getLocal()->push(val);
00065 else
00066 pushBuffer.getRemote(mindex)->push(val);
00067 }
00068
00069 template<typename ItTy>
00070 void push(ItTy b, ItTy e) {
00071 while (b != e)
00072 push(*b++);
00073 }
00074
00075 template<typename RangeTy>
00076 void push_initial(const RangeTy& range) {
00077 auto rp = range.local_pair();
00078 push(rp.first, rp.second);
00079 for (unsigned int x = 0; x < pushBuffer.size(); ++x)
00080 pushBuffer.getRemote(x)->flush();
00081 }
00082
00083 Galois::optional<value_type> pop() {
00084 cWL& wl = *items.getLocal();
00085 Galois::optional<value_type> retval = wl.pop();
00086 if (retval)
00087 return retval;
00088 pWL& p = *pushBuffer.getLocal();
00089 while ((retval = p.pop()))
00090 wl.push(*retval);
00091 return wl.pop();
00092 }
00093 };
00094 GALOIS_WLCOMPILECHECK(OwnerComputes)
00095
00096
00097 }
00098 }
00099
00100 #endif