00001 00023 #ifndef GALOIS_USERCONTEXT_H 00024 #define GALOIS_USERCONTEXT_H 00025 00026 #include "Galois/Mem.h" 00027 #include "Galois/gdeque.h" 00028 00029 #include "Galois/Runtime/Context.h" 00030 #include "Galois/Runtime/MethodFlags.h" 00031 00032 namespace Galois { 00033 00038 template<typename T> 00039 class UserContext: private boost::noncopyable { 00040 protected: 00041 // TODO: move to a separate class for dedicated for sepculative executors 00042 #ifdef GALOIS_USE_EXP 00043 using Closure = std::function<void (void)>; 00044 using UndoLog = Galois::gdeque<Closure, 8>; 00045 using CommitLog = UndoLog; 00046 00047 UndoLog undoLog; 00048 CommitLog commitLog; 00049 #endif 00050 00052 IterAllocBaseTy IterationAllocatorBase; 00053 PerIterAllocTy PerIterationAllocator; 00054 00055 void __resetAlloc() { 00056 IterationAllocatorBase.clear(); 00057 } 00058 00059 #ifdef GALOIS_USE_EXP 00060 void __rollback() { 00061 for (auto ii = undoLog.end (), ei = undoLog.begin(); ii != ei; ) { 00062 --ii; 00063 (*ii)(); 00064 } 00065 } 00066 00067 void __commit() { 00068 for (auto ii = commitLog.begin (), ei = commitLog.end(); ii != ei; ++ii) { 00069 (*ii)(); 00070 } 00071 } 00072 00073 void __resetUndoLog() { 00074 undoLog.clear(); 00075 } 00076 00077 void __resetCommitLog() { 00078 commitLog.clear(); 00079 } 00080 #endif 00081 00083 typedef gdeque<T> PushBufferTy; 00084 PushBufferTy pushBuffer; 00085 00086 PushBufferTy& __getPushBuffer() { 00087 return pushBuffer; 00088 } 00089 00090 void __resetPushBuffer() { 00091 pushBuffer.clear(); 00092 } 00093 00094 void* localState; 00095 bool localStateUsed; 00096 void __setLocalState(void *p, bool used) { 00097 localState = p; 00098 localStateUsed = used; 00099 } 00100 00101 static const unsigned int fastPushBackLimit = 64; 00102 00103 typedef std::function<void(PushBufferTy&)> FastPushBack; 00104 FastPushBack fastPushBack; 00105 void __setFastPushBack(FastPushBack f) { 00106 fastPushBack = f; 00107 } 00108 00109 bool* didBreak; 00110 00111 public: 00112 UserContext() 00113 :IterationAllocatorBase(), 00114 PerIterationAllocator(&IterationAllocatorBase), 00115 didBreak(0) 00116 { } 00117 00119 void breakLoop() { 00120 *didBreak = true; 00121 } 00122 00124 PerIterAllocTy& getPerIterAlloc() { 00125 return PerIterationAllocator; 00126 } 00127 00129 template<typename... Args> 00130 void push(Args&&... args) { 00131 Galois::Runtime::checkWrite(MethodFlag::WRITE, true); 00132 pushBuffer.emplace_back(std::forward<Args>(args)...); 00133 if (fastPushBack && pushBuffer.size() > fastPushBackLimit) 00134 fastPushBack(pushBuffer); 00135 } 00136 00138 void abort() { Galois::Runtime::forceAbort(); } 00139 00141 void* getLocalState(bool& used) { used = localStateUsed; return localState; } 00142 00143 #ifdef GALOIS_USE_EXP 00144 void addUndoAction(const Closure& f) { 00145 undoLog.push_back(f); 00146 } 00147 00148 void addCommitAction(const Closure& f) { 00149 commitLog.push_back(f); 00150 } 00151 #endif 00152 }; 00153 00154 } 00155 00156 #endif