7 struct Closure
: public PUP::able
{
8 virtual void pup(PUP::er
& p
) = 0;
9 PUPable_abstract(Closure
);
11 // reference count and self-destruct when no continuations have a reference
12 void ref() { continuations
++; }
13 void deref() { if (--continuations
<= 0) delete this; }
14 // done this way to keep Closure abstract for PUP reasons
15 // these must be called by descendents of Closure
16 void packClosure(PUP::er
& p
) { p
| continuations
; }
17 void init() { continuations
= 1; }
18 virtual ~Closure() { }
29 #include <debug-charm.h>
34 struct TransportableBigSimLog
: public Closure
{
36 TransportableBigSimLog() : log(0) { init(); }
37 TransportableBigSimLog(CkMigrateMessage
*) : log(0) { init(); }
39 TransportableBigSimLog(void* log
)
40 : log(log
) { init(); }
42 void pup(PUP::er
& p
) {
43 if (p
.isUnpacking()) log
= 0;
45 CkAbort("BigSim logs stored by SDAG are not migratable\n");
48 PUPable_decl(TransportableBigSimLog
);
51 struct ForallClosure
: public Closure
{
53 ForallClosure() : val(0) { init(); }
54 ForallClosure(CkMigrateMessage
*) : val(0) { init(); }
55 ForallClosure(int val
) : val(val
) { init(); }
57 void pup(PUP::er
& p
) {
61 PUPable_decl(ForallClosure
);
62 int& getP0() { return val
; }
65 struct MsgClosure
: public Closure
{
68 MsgClosure() : msg(0) { init(); continuations
= 0; }
69 MsgClosure(CkMigrateMessage
*) : msg(0) { init(); continuations
= 0; }
75 CmiReference(UsrToEnv(msg
));
78 void pup(PUP::er
& p
) {
81 if (hasMsg
) CkPupMessage(p
, (void**)&msg
);
82 if (hasMsg
&& p
.isUnpacking())
83 CmiReference(UsrToEnv(msg
));
87 virtual ~MsgClosure() {
88 if (msg
) CmiFree(UsrToEnv(msg
));
91 PUPable_decl(MsgClosure
);
94 class CCounter
: public Closure
{
98 CCounter() { init(); }
99 CCounter(CkMigrateMessage
*) { init(); }
100 CCounter(int c
) : count(c
) { init(); }
101 CCounter(int first
, int last
, int stride
) {
103 count
= ((last
- first
) / stride
) + 1;
105 void decrement(void) { count
--; }
106 int isDone(void) { return (count
== 0); }
108 void pup(PUP::er
& p
) {
112 PUPable_decl(CCounter
);
115 struct CSpeculator
: public Closure
{
116 int speculationIndex
;
118 CSpeculator() : speculationIndex(0) { init(); }
119 CSpeculator(CkMigrateMessage
*) : speculationIndex(0) { init(); }
121 CSpeculator(int speculationIndex_
)
122 : speculationIndex(speculationIndex_
) { init(); }
124 void pup(PUP::er
& p
) {
125 p
| speculationIndex
;
128 PUPable_decl(CSpeculator
);
131 struct Continuation
: public PUP::able
{
133 std::vector
<Closure
*> closure
;
134 std::vector
<CMK_REFNUM_TYPE
> entries
, refnums
;
135 std::vector
<int> anyEntries
;
136 int speculationIndex
;
138 Continuation() : speculationIndex(-1) { }
139 Continuation(CkMigrateMessage
*) : speculationIndex(-1) { }
141 Continuation(int whenID
)
143 , speculationIndex(-1) { }
145 void pup(PUP::er
& p
) {
151 p
| speculationIndex
;
154 void addClosure(Closure
* cl
) {
156 closure
.push_back(cl
);
159 virtual ~Continuation() {
160 for (int i
= 0; i
< closure
.size(); i
++)
165 PUPable_decl(Continuation
);
168 struct Buffer
: public PUP::able
{
170 CMK_REFNUM_TYPE refnum
;
174 void *bgLog1
, *bgLog2
;
177 Buffer(CkMigrateMessage
*) { }
179 Buffer(int entry
, Closure
* cl
, CMK_REFNUM_TYPE refnum
)
191 void pup(PUP::er
& p
) {
203 else if (bgLog1
!= 0 && bgLog2
!= 0)
204 CkAbort("BigSim logs stored by SDAG are not migratable\n");
212 PUPable_decl(Buffer
);
216 std::vector
<std::list
<int> > entryToWhen
;
217 std::vector
<std::list
<Continuation
*> > whenToContinuation
;
219 // entry -> lst of buffers
220 // @todo this will have sequential lookup time for specific reference
222 std::vector
<std::list
<Buffer
*> > buffer
;
224 int curSpeculationIndex
;
226 void pup(PUP::er
& p
) {
227 p
| curSpeculationIndex
;
230 p
| whenToContinuation
;
233 Dependency(int numEntries
, int numWhens
)
234 : entryToWhen(numEntries
)
235 , whenToContinuation(numWhens
)
237 , curSpeculationIndex(0)
240 // after a migration free the structures
242 for (std::vector
<std::list
<Buffer
*> >::iterator iter
= buffer
.begin();
243 iter
!= buffer
.end(); ++iter
) {
244 std::list
<Buffer
*> lst
= *iter
;
245 for (std::list
<Buffer
*>::iterator iter2
= lst
.begin();
246 iter2
!= lst
.end(); ++iter2
) {
251 for (int i
= 0; i
< whenToContinuation
.size(); i
++) {
252 for (std::list
<Continuation
*>::iterator iter2
= whenToContinuation
[i
].begin();
253 iter2
!= whenToContinuation
[i
].end(); ++iter2
) {
259 void addDepends(int whenID
, int entry
) {
260 entryToWhen
[entry
].push_back(whenID
);
263 void reg(Continuation
*c
) {
264 //printf("registering new continuation %p, whenID = %d\n", c, c->whenID);
265 whenToContinuation
[c
->whenID
].push_back(c
);
268 void dereg(Continuation
*c
) {
269 CkAssert(c
->whenID
< whenToContinuation
.size());
270 std::list
<Continuation
*>& lst
= whenToContinuation
[c
->whenID
];
274 Buffer
* pushBuffer(int entry
, Closure
*cl
, CMK_REFNUM_TYPE refnum
) {
275 Buffer
* buf
= new Buffer(entry
, cl
, refnum
);
276 buffer
[entry
].push_back(buf
);
280 Continuation
*tryFindContinuation(int entry
) {
281 for (std::list
<int>::iterator iter
= entryToWhen
[entry
].begin();
282 iter
!= entryToWhen
[entry
].end();
286 for (std::list
<Continuation
*>::iterator iter2
= whenToContinuation
[whenID
].begin();
287 iter2
!= whenToContinuation
[whenID
].end();
289 Continuation
* c
= *iter2
;
290 if (searchBufferedMatching(c
)) {
296 //printf("no continuation found\n");
300 bool searchBufferedMatching(Continuation
* t
) {
301 CkAssert(t
->entries
.size() == t
->refnums
.size());
302 for (int i
= 0; i
< t
->entries
.size(); i
++) {
303 if (!tryFindMessage(t
->entries
[i
], true, t
->refnums
[i
], 0)) {
307 for (int i
= 0; i
< t
->anyEntries
.size(); i
++) {
308 if (!tryFindMessage(t
->anyEntries
[i
], false, 0, 0)) {
315 Buffer
* tryFindMessage(int entry
, bool hasRef
, CMK_REFNUM_TYPE refnum
, std::set
<Buffer
*>* ignore
) {
316 // @todo sequential lookup for buffer with reference number or ignore set
317 for (std::list
<Buffer
*>::iterator iter
= buffer
[entry
].begin();
318 iter
!= buffer
[entry
].end();
320 if ((!hasRef
|| (*iter
)->refnum
== refnum
) &&
321 (!ignore
|| ignore
->find(*iter
) == ignore
->end()))
327 Buffer
* tryFindMessage(int entry
) {
328 if (buffer
[entry
].size() == 0)
331 return buffer
[entry
].front();
334 void removeMessage(Buffer
*buf
) {
335 buffer
[buf
->entry
].remove(buf
);
338 int getAndIncrementSpeculationIndex() {
339 return curSpeculationIndex
++;
342 void removeAllSpeculationIndex(int speculationIndex
) {
343 for (std::vector
<std::list
<Continuation
*> >::iterator iter
= whenToContinuation
.begin();
344 iter
!= whenToContinuation
.end();
346 std::list
<Continuation
*>& lst
= *iter
;
348 for (std::list
<Continuation
*>::iterator iter2
= lst
.begin();
350 //cppcheck-suppress StlMissingComparison
352 if ((*iter2
)->speculationIndex
== speculationIndex
) {
353 Continuation
*cancelled
= *iter2
;
354 //cppcheck-suppress StlMissingComparison
355 iter2
= lst
.erase(iter2
);
365 void registerPUPables();