28c18121c8cc9cc6869815d4a2b94ae2fd8fa8e2
[charm.git] / src / libs / ck-libs / tcharm / tcharm.h
1 /*
2 Threaded Charm++ "Framework Framework" 
3
4 This is the interface used by library writers--
5 people who use TCharm to build their own library.
6
7 Orion Sky Lawlor, olawlor@acm.org, 7/17/2002
8 */
9 #ifndef __CHARM_TCHARMLIB_H
10 #define __CHARM_TCHARMLIB_H
11
12 #include "tcharm_impl.h"
13
14 /*
15 Library "fallback setup" routine.
16 From an initcall, you register one of your routines 
17 here in case the user doesn't write a TCHARM_User_setup
18 routine.  Your fallback version sets up (only) your 
19 library by creating some TCharm threads and attaching to them,
20 like:
21
22 void myLibFallbackSetupFn(void) {
23         TCHARM_Create(TCHARM_Get_num_chunks(),myLibUserStart);
24         myLib_Attach();
25 }
26 */
27 typedef void (*TCHARM_Fallback_setup_fn)(void);
28 void TCHARM_Set_fallback_setup(TCHARM_Fallback_setup_fn f);
29
30
31 /*
32 These two routines need to be called from your Attach routine.
33 The "start" call finds the last-created set of tcharm threads,
34 copies their arrayID into retTCharmArray, and returns an 
35 opts object bound the the tcharm threads.  You pass this opts
36 object to your array's ckNew.
37 The "finish" call registers your newly-created array as a
38 client of this set of TCharm threads.
39 */
40 CkArrayOptions TCHARM_Attach_start(CkArrayID *retTCharmArray,int *retNumElts=0);
41 void TCHARM_Attach_finish(const CkArrayID &libraryArray);
42
43
44 /*
45 A simple client array that can be bound to a tcharm array.
46 You write a TCharm library by inheriting your array from this class.
47 You'll have to pass the TCharm arrayID to our constructor, and
48 then call tcharmClientInit().
49 As soon as your startup work is done, you MUST call "thread->ready();"
50 */
51 class TCharmClient1D : public ArrayElement1D {
52   CProxy_TCharm threadProxy; //Proxy for our bound TCharm array
53  protected:
54   /* This is the actual TCharm object that manages our thread.
55      You use this like "thread->suspend();", "thread->resume();",
56      etc.  
57    */
58   TCharm *thread; 
59   inline void findThread(void) {
60     thread=threadProxy[thisIndex].ckLocal();  
61     if (thread==NULL) CkAbort("Can't locate TCharm thread!");
62   }
63   
64   //Clients need to override this function to set their
65   // thread-private variables.  You usually use something like:
66   //  CtvAccessOther(forThread,_myFooPtr)=this;
67   virtual void setupThreadPrivate(CthThread forThread) =0;
68   
69  public:
70   TCharmClient1D(const CkArrayID &threadArrayID) 
71     :threadProxy(threadArrayID)
72   {
73     //Argh!  Can't call setupThreadPrivate yet, because
74     // virtual functions don't work within constructors!
75     findThread();
76   }
77   TCharmClient1D(CkMigrateMessage *m) //Migration, etc. constructor
78   {
79     thread=NULL;
80   }
81   
82   //You MUST call this from your constructor:
83   inline void tcharmClientInit(void) {
84     setupThreadPrivate(thread->getThread());
85   }
86   
87   virtual void ckJustMigrated(void);
88   virtual void pup(PUP::er &p);
89 };
90
91
92 /*
93 Library API Calls.  The pattern:
94   TCHARM_API_TRACE("myRoutineName","myLibName");
95 MUST be put at the start of every
96 user-callable library routine.  The string name is
97 used for debugging printouts, and eventually for
98 tracing (once tracing is generalized).
99 */
100 #ifndef CMK_OPTIMIZE
101 #  define TCHARM_API_TRACE(routineName,libraryName) \
102         TCharmAPIRoutine apiRoutineSentry;\
103         TCHARM_Api_trace(routineName,libraryName)
104 #else
105 #  define TCHARM_API_TRACE(routineName,libraryName) \
106         TCharmAPIRoutine apiRoutineSentry
107 #endif
108 void TCHARM_Api_trace(const char *routineName,const char *libraryName);
109
110
111 /* Get the currently running TCharm threads: */
112 CkArrayID TCHARM_Get_threads(void);
113
114 #endif /*def(thisHeader)*/