Drastic simplification of TCharm's startup sequence:
[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 with the appropriate
20 "start running" routine, like this:
21
22 void myLibFallbackSetupFn(void) {
23         TCHARM_Create(TCHARM_Get_num_chunks(),myLibUserStart);
24 }
25
26 In case of multiple fallback setups, the last one wins.
27 */
28 typedef void (*TCHARM_Fallback_setup_fn)(void);
29 void TCHARM_Set_fallback_setup(TCHARM_Fallback_setup_fn f);
30
31 /*
32 This "start" call finds the currently running set of tcharm threads,
33 copies their arrayID into retTCharmArray, and returns an 
34 opts object bound the the tcharm threads.  In your library
35 "Init" routine, you normally pass this opts object to your 
36 array's ckNew, then block until the startup is complete 
37 (often using TCharm::semaGet).
38 */
39 CkArrayOptions TCHARM_Attach_start(CkArrayID *retTCharmArray,int *retNumElts=0);
40
41 /* Get the currently running TCharm threads: */
42 CkArrayID TCHARM_Get_threads(void);
43
44 /// Suspend the current thread.  Resume by calling thread->resume().
45 void TCHARM_Suspend(void);
46
47 /*
48 A simple client array that can be bound to a tcharm array.
49 You write a TCharm library by inheriting your array from this class.
50 You'll have to pass the TCharm arrayID to our constructor, and
51 then call tcharmClientInit().
52 */
53 class TCharmClient1D : public ArrayElement1D {
54   CProxy_TCharm threadProxy; //Proxy for our bound TCharm array
55  protected:
56   /* This is the actual TCharm object that manages our thread.
57      You use this like "thread->suspend();", "thread->resume();",
58      etc.  
59    */
60   TCharm *thread; 
61   inline void findThread(void) {
62     thread=threadProxy[thisIndex].ckLocal();  
63     if (thread==NULL) CkAbort("Can't locate TCharm thread!");
64   }
65   
66   //Clients need to override this function to set their
67   // thread-private variables.  You usually use something like:
68   //  CtvAccessOther(forThread,_myFooPtr)=this;
69   virtual void setupThreadPrivate(CthThread forThread) =0;
70   
71  public:
72   TCharmClient1D(const CkArrayID &threadArrayID) 
73     :threadProxy(threadArrayID)
74   {
75     //Argh!  Can't call setupThreadPrivate yet, because
76     // virtual functions don't work within constructors!
77     findThread();
78   }
79   TCharmClient1D(CkMigrateMessage *m) //Migration, etc. constructor
80   {
81     thread=NULL;
82   }
83   
84   //You MUST call this from your constructor:
85   inline void tcharmClientInit(void) {
86     setupThreadPrivate(thread->getThread());
87   }
88   
89   virtual void ckJustMigrated(void);
90   virtual void pup(PUP::er &p);
91 };
92
93
94 /*
95 Library API Calls.  The pattern:
96   TCHARM_API_TRACE("myRoutineName","myLibName");
97 MUST be put at the start of every user-callable library 
98 routine, to turn off isomalloc'd heaps before jumping
99 into regular Charm.  The string routineName is
100 used for debugging printouts, with "+tcharm_trace myLibName".
101 */
102 #ifndef CMK_OPTIMIZE
103 #  define TCHARM_API_TRACE(routineName,libraryName) \
104         TCharmAPIRoutine apiRoutineSentry;\
105         TCHARM_Api_trace(routineName,libraryName)
106 #else
107 #  define TCHARM_API_TRACE(routineName,libraryName) \
108         TCharmAPIRoutine apiRoutineSentry
109 #endif
110 void TCHARM_Api_trace(const char *routineName,const char *libraryName);
111
112
113 #endif /*def(thisHeader)*/