Removed old checkpoint/restart mechanism
[charm.git] / src / libs / ck-libs / tcharm / tcharm_impl.h
1 /*
2 Threaded Charm++ "Framework Framework" Implementation header
3
4 Implements an array of migratable threads.
5 Provides utility routines for registering user
6 data, stopping, starting, and migrating threads.
7
8 Orion Sky Lawlor, olawlor@acm.org, 11/19/2001
9 */
10 #ifndef __CHARM_TCHARM_IMPL_H
11 #define __CHARM_TCHARM_IMPL_H
12
13 #include "pup.h"
14 #include "pup_c.h"
15 #include "charm-api.h"
16 #include "tcharmc.h"
17 #include "cklists.h"
18 #include "memory-isomalloc.h"
19
20 //User's readonly global variables, set exactly once after initialization
21 class TCharmReadonlys {
22         //There's only one (shared) list per node, so no CpvAccess here
23         static CkVec<TCpupReadonlyGlobal> entries;
24  public:
25         static void add(TCpupReadonlyGlobal fn);
26         //Pups all registered readonlys 
27         static void pupAllReadonlys(PUP::er &p);
28
29         //Used by parameter marshalling:
30         void pup(PUP::er &p);
31 };
32 PUPmarshall(TCharmReadonlys);
33
34 class TCharmTraceLibList;
35
36 #include "tcharm.decl.h"
37
38 class TCharmReadonlyGroup : public Group {
39  public:
40         //Just unpacking the parameter is enough:
41         TCharmReadonlyGroup(const TCharmReadonlys &r) { /*nothing needed*/ }
42 };
43
44 class TCharm;
45
46 class TCharmInitMsg : public CMessage_TCharmInitMsg {
47  public:
48         //Function to start thread with:
49         CthVoidFn threadFn;
50         //Initial stack size, in bytes:
51         int stackSize;
52         //Array size (number of elements)
53         int numElements;
54         //Data to pass to thread:
55         char *data;
56
57         TCharmInitMsg(CthVoidFn threadFn_,int stackSize_)
58                 :threadFn(threadFn_), stackSize(stackSize_) {}
59 };
60
61 //Current computation location
62 typedef enum {inNodeSetup,inInit,inDriver,inFramework,inPup} inState;
63
64 //Thread-local variables:
65 CtvExtern(TCharm *,_curTCharm);
66 CpvExtern(inState,_stateTCharm);
67
68 CDECL {typedef void (*TCpupUserDataC)(pup_er p,void *data);};
69 FDECL {typedef void (*TCpupUserDataF)(pup_er p,void *data);};
70
71 class TCharm: public ArrayElement1D
72 {
73  public:
74
75         //User's heap-allocated/global data:
76         class UserData {
77                 void *data; //user data pointer
78                 bool isC;
79                 TCpupUserDataC cfn;
80                 TCpupUserDataF ffn;
81         public:
82                 UserData(int i=0) {data=NULL; cfn=NULL; ffn=NULL;}
83                 UserData(TCpupUserDataC cfn_,void *data_)
84                         {cfn=cfn_; data=data_; isC=true;}
85                 class isFortran{};
86                 UserData(TCpupUserDataF ffn_,void *data_,isFortran tag)
87                         {ffn=ffn_; data=data_; isC=false;}
88                 inline void *getData(void) const {return data;}
89                 void pup(PUP::er &p);
90                 friend inline void operator|(PUP::er &p,UserData &d) {d.pup(p);}
91         };
92         //New interface for user data:
93         CkVec<UserData> sud;
94
95         //One-time initialization
96         static void nodeInit(void);
97  private:
98         //Informational data about the current thread:
99         class ThreadInfo {
100         public:
101                 CProxy_TCharm tProxy; //Our proxy
102                 int thisElement; //Index of current element
103                 int numElements; //Number of array elements
104         };
105
106         TCharmInitMsg *initMsg; //Thread initialization data
107         CthThread tid; //Our migratable thread
108         friend class TCharmAPIRoutine; //So he can get to heapBlocks:
109         CmiIsomallocBlockList *heapBlocks; //Migratable heap data
110
111         bool isStopped;
112         ThreadInfo threadInfo;
113         double timeOffset; //Value to add to CkWallTimer to get my clock
114
115         //Old interface for user data:
116         enum {maxUserData=16};
117         int nUd;
118         UserData ud[maxUserData];
119
120         void ResumeFromSync(void);
121
122 #ifdef CMK_OPTIMIZE
123         static inline void check(void) {}
124 #else
125         static void check(void);
126 #endif
127
128  public:
129         TCharm(TCharmInitMsg *initMsg);
130         TCharm(CkMigrateMessage *);
131         ~TCharm();
132
133         void clear();
134
135         //Pup routine packs the user data and migrates the thread
136         virtual void pup(PUP::er &p);
137
138         //Start running the thread for the first time
139         void run(void);
140
141         inline double getTimeOffset(void) const { return timeOffset; }
142
143 //Client-callable routines:
144         //One client is ready to run
145         void ready(void);
146
147         //Sleep till entire array is here
148         void barrier(void);
149
150         //Thread finished running
151         void done(void);
152
153         //Register user data to be packed with the thread
154         int add(const UserData &d);
155         void *lookupUserData(int ud);
156         
157         inline static TCharm *get(void) {check(); return CtvAccess(_curTCharm);}
158         inline static inState getState(void) {return CpvAccess(_stateTCharm);}
159         inline static void setState(inState to) {CpvAccess(_stateTCharm)=to;}
160         inline CthThread getThread(void) {return tid;}
161         inline const CProxy_TCharm &getProxy(void) const {return threadInfo.tProxy;}
162         inline int getElement(void) const {return threadInfo.thisElement;}
163         inline int getNumElements(void) const {return threadInfo.numElements;}
164
165         //Start/stop load balancer measurements
166         inline void stopTiming(void) {ckStopTiming();}
167         inline void startTiming(void) {ckStartTiming();}
168
169         //Block our thread, run the scheduler, and come back
170         inline void schedule(void) {
171                 stopTiming();
172                 CthYield();
173                 startTiming();
174         }
175
176         //As above, but start/stop the thread itself, too.
177         void stop(void); //Blocks; will not return until "start" called.
178         void start(void);
179         //Aliases:
180         inline void suspend(void) {stop();}
181         inline void resume(void) {start();}
182
183         //Go to sync, block, possibly migrate, and then resume
184         void migrate(void);
185
186         //Make subsequent malloc's go into our list:
187         inline void activateHeap(void) {
188                 CmiIsomallocBlockListActivate(heapBlocks);
189         }
190         //Disable migratable memory
191         inline void deactivateHeap(void) {
192                 CmiIsomallocBlockListActivate(NULL);
193         }
194 };
195
196
197
198 //TCharm internal class: Controls array startup, ready, run and shutdown
199 class TCharmCoordinator {
200         static int nArrays; //Total number of running thread arrays
201         static TCharmCoordinator *head; //List of coordinators
202
203         TCharmCoordinator *next; //Next coordinator in list
204         CProxy_TCharm threads;//The threads I coordinate
205         int nThreads;//Number of threads (array elements)
206         int nClients; //Number of bound client arrays
207         int nReady; //Number of ready clients
208 public:
209         TCharmCoordinator(CkArrayID threads,int nThreads);
210         ~TCharmCoordinator();
211         void addClient(const CkArrayID &client);
212         void clientReady(void);
213         void clientBarrier(void);
214         void clientDone(void);
215         
216         static int getTotal(void) {
217                 return nArrays;
218         }
219 };
220
221 //Controls initial setup (main::main & init routines)
222 class TCharmSetupCookie {
223         enum {correctMagic=0x5432abcd};
224         int magic; //To make sure this is actually a cookie
225         
226         int stackSize; //Thread stack size, in bytes
227         char **argv; //Command-line arguments
228         
229         CkArrayID tc; //Handle to last-created TCharm array
230         int numElements; //Number of elements in last-created TCharm
231         TCharmCoordinator *coord; 
232
233         //Points to the active cookie
234         static TCharmSetupCookie *theCookie;
235         friend class TCharmMain;
236  public:
237         TCharmSetupCookie(char **argv_);
238         
239 #ifdef CMK_OPTIMIZE //Skip check, for speed
240         inline TCharmSetupCookie &check(void) {return *this;}
241 #else
242         TCharmSetupCookie &check(void);
243 #endif
244         void setStackSize(int sz) {stackSize=sz;}
245         int getStackSize(void) const {return stackSize;}
246         char **getArgv(void) {return argv;}
247         
248         bool hasThreads(void) const {return 0!=coord;}
249         const CkArrayID &getThreads(void) const {return tc;}
250         TCharmCoordinator *getCoordinator(void) {return coord;}
251         int getNumElements(void) const {return numElements;}
252
253         void addClient(const CkArrayID &client) {coord->addClient(client);}
254         
255         void setThreads(const CkArrayID &aid,int nel);
256
257         static TCharmSetupCookie *get(void) {return theCookie;}
258 };
259
260 //Created in all API routines: disables/enables migratable malloc
261 class TCharmAPIRoutine {
262  public:
263         TCharmAPIRoutine() { //Entering Charm++ from user code
264                 //Disable migratable memory allocation while in Charm++:
265                 CmiIsomallocBlockListActivate(NULL);
266         }
267         ~TCharmAPIRoutine() { //Returning to user code from Charm++:
268                 //Reenable migratable memory allocation
269                 TCharm *tc=CtvAccess(_curTCharm);
270                 if (tc!=NULL) tc->activateHeap();
271         }
272 };
273
274
275 #define TCHARMAPI(routineName) TCHARM_API_TRACE(routineName,"tcharm");
276
277 //Node setup callbacks: called at startup on each node
278 FDECL void FTN_NAME(TCHARM_USER_NODE_SETUP,tcharm_user_node_setup)(void);
279 FDECL void FTN_NAME(TCHARM_USER_SETUP,tcharm_user_setup)(void);
280
281
282 #endif
283
284