00001
00023 #ifndef GALOIS_WORKLIST_LOCALQUEUE_H
00024 #define GALOIS_WORKLIST_LOCALQUEUE_H
00025
00026 #include "Galois/config.h"
00027 #include <boost/mpl/if.hpp>
00028 #include GALOIS_CXX11_STD_HEADER(type_traits)
00029
00030 namespace Galois {
00031 namespace WorkList {
00032
00033 template<typename T = int>
00034 struct NoGlobalQueue {
00035 template<bool _concurrent>
00036 struct rethread { typedef NoGlobalQueue<T> type; };
00037
00038 template<typename _T>
00039 struct retype { typedef NoGlobalQueue<_T> type; };
00040 };
00041
00042 template<typename Global = NoGlobalQueue<>, typename Local = FIFO<>, typename T = int>
00043 struct LocalQueue : private boost::noncopyable {
00044 template<bool _concurrent>
00045 struct rethread { typedef LocalQueue<Global, Local, T> type; };
00046
00047 template<typename _T>
00048 struct retype { typedef LocalQueue<typename Global::template retype<_T>::type, typename Local::template retype<_T>::type, _T> type; };
00049
00050 template<typename _global>
00051 struct with_global { typedef LocalQueue<_global, Local, T> type; };
00052
00053 template<typename _local>
00054 struct with_local { typedef LocalQueue<Global, _local, T> type; };
00055
00056 private:
00057 typedef typename Local::template rethread<false>::type lWLTy;
00058 Runtime::PerThreadStorage<lWLTy> local;
00059 Global global;
00060
00061 template<typename RangeTy, bool Enable = std::is_same<Global,NoGlobalQueue<T> >::value>
00062 void pushGlobal(const RangeTy& range, typename std::enable_if<Enable>::type* = 0) {
00063 auto rp = range.local_pair();
00064 local.getLocal()->push(rp.first, rp.second);
00065 }
00066
00067 template<typename RangeTy, bool Enable = std::is_same<Global,NoGlobalQueue<T> >::value>
00068 void pushGlobal(const RangeTy& range, typename std::enable_if<!Enable>::type* = 0) {
00069 global.push_initial(range);
00070 }
00071
00072 template<bool Enable = std::is_same<Global,NoGlobalQueue<T> >::value>
00073 Galois::optional<T> popGlobal(typename std::enable_if<Enable>::type* = 0) {
00074 return Galois::optional<value_type>();
00075 }
00076
00077 template<bool Enable = std::is_same<Global,NoGlobalQueue<T> >::value>
00078 Galois::optional<T> popGlobal(typename std::enable_if<!Enable>::type* = 0) {
00079 return global.pop();
00080 }
00081
00082 public:
00083 typedef T value_type;
00084
00085 void push(const value_type& val) {
00086 local.getLocal()->push(val);
00087 }
00088
00089 template<typename Iter>
00090 void push(Iter b, Iter e) {
00091 local.getLocal()->push(b,e);
00092 }
00093
00094 template<typename RangeTy>
00095 void push_initial(const RangeTy& range) {
00096 pushGlobal(range);
00097 }
00098
00099 Galois::optional<value_type> pop() {
00100 Galois::optional<value_type> ret = local.getLocal()->pop();
00101 if (ret)
00102 return ret;
00103 return popGlobal();
00104 }
00105 };
00106 GALOIS_WLCOMPILECHECK(LocalQueue)
00107
00108 }
00109 }
00110
00111 #endif