20 #ifndef GALOIS_SUBSTRATE_TERMINATION_H
21 #define GALOIS_SUBSTRATE_TERMINATION_H
25 #include "galois/config.h"
32 class TerminationDetection;
77 template <
typename _UNUSED =
void>
78 class LocalTerminationDetection :
public TerminationDetection {
81 friend class TerminationDetection;
82 std::atomic<long> tokenIsBlack;
83 std::atomic<long> hasToken;
93 void propToken(
bool isBlack) {
96 th.tokenIsBlack = isBlack;
108 LocalTerminationDetection() {}
111 TokenHolder& th = *data.getLocal();
112 th.tokenIsBlack =
false;
113 th.processIsBlack =
true;
114 th.lastWasWhite =
true;
124 TokenHolder& th = *data.getLocal();
125 th.processIsBlack |= workHappened;
128 bool failed = th.tokenIsBlack || th.processIsBlack;
129 th.tokenIsBlack = th.processIsBlack =
false;
130 if (th.lastWasWhite && !failed) {
135 th.lastWasWhite = !failed;
139 "no token should be in progress after globalTerm");
140 bool taint = th.processIsBlack || th.tokenIsBlack;
141 th.processIsBlack = th.tokenIsBlack =
false;
149 template <
typename _UNUSED =
void>
150 class TreeTerminationDetection :
public TerminationDetection {
151 static const int num = 2;
154 friend class TerminationDetection;
156 volatile long down_token;
158 volatile long up_token[num];
165 TokenHolder* child[num];
168 PerThreadStorage<TokenHolder> data;
172 void processToken() {
173 TokenHolder& th = *data.getLocal();
176 bool haveAll = th.hasToken;
177 bool black = th.processIsBlack;
178 for (
int i = 0; i < num; ++i) {
180 if (th.up_token[i] == -1)
183 black |= th.up_token[i];
188 th.processIsBlack =
false;
191 if (th.lastWasWhite && !black) {
196 th.lastWasWhite = !black;
197 th.down_token =
true;
199 data.getRemote(th.parent)->up_token[th.parent_offset] = black;
205 th.down_token =
false;
207 for (
int i = 0; i < num; ++i) {
210 th.child[i]->down_token =
true;
223 TreeTerminationDetection() {}
226 TokenHolder& th = *data.getLocal();
227 th.down_token =
false;
228 for (
int i = 0; i < num; ++i)
229 th.up_token[i] =
false;
230 th.processIsBlack =
true;
232 th.lastWasWhite =
false;
235 th.parent = (tid - 1) / num;
236 th.parent_offset = (tid - 1) % num;
237 for (
unsigned i = 0; i < num; ++i) {
238 unsigned cn = tid * num + i + 1;
240 th.child[i] = data.getRemote(cn);
245 th.down_token =
true;
251 TokenHolder& th = *data.getLocal();
252 th.processIsBlack |= workHappened;
257 void setTermDetect(TerminationDetection* term);
CacheLineStorage< std::atomic< int > > globalTerm
Definition: Termination.h:44
virtual void initializeThread()=0
Initializes the per-thread state.
virtual void localTermination(bool workHappened)=0
Process termination locally.
friend TerminationDetection & getSystemTermination(unsigned)
Definition: CacheLineStorage.h:32
bool globalTermination() const
Returns whether global termination is detected.
Definition: Termination.h:72
void init(const RangeTy &range)
Definition: Executor_ParaMeter.h:409
T & get()
Definition: CacheLineStorage.h:46
TerminationDetection & getSystemTermination(unsigned activeThreads)
Definition: Termination.cpp:35
virtual ~TerminationDetection(void)
Definition: Termination.cpp:24
static unsigned getTID()
Definition: ThreadPool.h:204
Definition: PerThreadStorage.h:88
unsigned int activeThreads
Definition: Threads.cpp:26
Definition: Termination.h:39
virtual void init(unsigned activeThreads)=0
for internal use by child classes
T data
Definition: CacheLineStorage.h:33