The new version of comlib! This version passed "make test" in charm/tests on order...
[charm.git] / src / conv-com / convcomlibmanager.h
1 #ifndef CONVCOMLIBMANAGER
2 #define CONVCOMLIBMANAGER
3
4
5 /**
6    @addtogroup ConvComlib
7    *@{
8    
9    @file
10    @brief Converse ComlibManager.
11    Declares the classes ConvComlibManager, plus
12    the interface provided to the user.
13    
14    * ConvComlibManager, responsible for the management of all the strategies in
15    the system, their initial broadcast and synchronization (at strategy
16    instantiation), as well as some runtime coordination. Mostly gives support
17    for the higher classes.
18     
19    The interface provided to the user es prefixed with "Comlib" except
20    ConvComlibRegister which has an extra prefix for compatibility with charm.
21
22    Sameer Kumar 28/03/04.
23    Heavily revised, Filippo Gioachin 01/06.
24 */
25
26 #include <convcomlibstrategy.h>
27 #include "ComlibStrategy.h"
28
29 // Are we crazy? Only 32 strategies allowed in the entire system?!?!?
30 #define MAX_NUM_STRATS 32
31
32
33 /** Converse interface to handle all the Comlib strategies registered in the
34     Converse of Charm++ program. Being in Converse, this is a pure class
35     allocated into a global variable. */
36 class ConvComlibManager {
37
38   /// a table containing all the strategies in the system
39   StrategyTable strategyTable;
40   /// it is true after the system has been initialized at the program startup
41   CmiBool init_flag;
42   /// the number of strategies currently present in the system
43   int nstrats;
44
45   friend Strategy::Strategy();
46   int insertStrategy(Strategy *s);
47  public:
48   // a few variables used in the process of strategy synchronization
49   /// count how many acks have been received for the current synchronization
50   int acksReceived;
51   /// used when a doneCreating is called before the previous one is finished
52   CmiBool doneCreatingScheduled;
53   /// true when the manager is busy synchronizing the strategies
54   CmiBool busy;
55
56   ConvComlibManager();
57
58   void setInitialized() {init_flag = CmiTrue;}
59   CmiBool getInitialized() {return init_flag;}
60
61   // used only by ComlibManager.C to broadcast the strategies: DEPRECATED!
62   // the broadcast has to be done by converse
63   //void insertStrategy(Strategy *s, int loc);
64
65   /** Used to broadcast all strategies to all processors after inserting them */
66   void doneCreating();
67   /** Switch all the strategies in the "inSync" status to "ready" and deposit
68       into the strategies all pending messages */
69   void tableReady();
70   void enableStrategy(int loc);
71
72  private:
73   inline void setStrategy(int loc, Strategy *s) {
74 #ifndef CMK_OPTIMIZE
75     if (loc == 0) CmiAbort("Trying to set strategy zero, not valid!\n");
76 #endif
77     strategyTable[loc].strategy = s;
78   }
79   friend void *comlibReceiveTableHandler(void *msg);
80  public:
81   inline int getNumStrats() {return nstrats;}
82   inline Strategy *getStrategy(int loc) {return strategyTable[loc].strategy;}
83   inline int isReady(int loc) {return strategyTable[loc].isReady;}
84   inline int isNew(int loc) {return strategyTable[loc].isNew;}
85   inline int isInSync(int loc) {return strategyTable[loc].isInSync;}
86   inline void inSync(int loc) {
87     strategyTable[loc].isNew = 0;
88     strategyTable[loc].isInSync = 1;
89   }
90   inline int getErrorMode(int loc) {return strategyTable[loc].errorMode;}
91   inline CkQ<MessageHolder*> *getTmpList(int loc) {return &strategyTable[loc].tmplist;}
92
93   
94   // TODO inline this function again
95   void insertMessage(MessageHolder* msg, int instid);
96   
97   inline void doneInserting(int loc) {
98           if (isReady(loc))
99                   strategyTable[loc].strategy->doneInserting();
100           else
101                   strategyTable[loc].call_doneInserting ++;
102   }
103
104   StrategyTableEntry *getStrategyTable(int loc) {return &strategyTable[loc];}
105   //StrategyTable *getStrategyTable() {return &strategyTable;}
106
107   void printDiagnostics();
108
109 };
110
111 /// The location in the global table where the converse Comlib manager is located.
112 CkpvExtern(ConvComlibManager, conv_com_object);
113 /// A pointer to the location of the converse Comlib manager.
114 CkpvExtern(ConvComlibManager *, conv_com_ptr);
115
116
117 void initComlibManager();
118
119 /***************************************************************************
120  * User section:
121  *
122  * Implementation of the functions used by the user
123  ***************************************************************************/
124
125 Strategy *ConvComlibGetStrategy(int loc);
126
127 /* Routine to register a Strategy to the system. It accept both Converse
128     strategies and higher level strategies. Strategies can be registered in all
129     the processors or only on processor 0. ComlibDoneCreating will take care of
130     the synchronization. Strategies are not active until they are synchronized.
131     If different processors register different strategies, or in different
132     order, the behaviour is undefined. */
133 /*  DELETED SINCE NOT ANYMORE USEFUL
134 inline ConvComlibInstanceHandle ConvComlibRegister(Strategy *s) {
135   return (CkpvAccess(conv_com_ptr))->insertStrategy(s);
136 }
137 */
138
139 /** Iterate over all the inserted strategies and broadcast all those that are
140     marked as new. This has some effect only on processor 0, for all the other
141     it is a NOP. */
142 inline void ComlibDoneCreating() {
143   if (CmiMyPe() != 0) return;
144   CkpvAccess(conv_com_object).doneCreating();
145 }
146
147 void ConvComlibScheduleDoneInserting(int loc);
148
149 /** Converse send utilities for comlib. For all of them the message passed will
150     be lost by the application. */
151 inline void ComlibSyncSendAndFree(unsigned int pe, unsigned int size, char *msg, ComlibInstanceHandle cinst) {
152   CkpvAccess(conv_com_object).insertMessage(new MessageHolder(msg, size, pe), cinst);
153 }
154
155 inline void ComlibSyncBroadcastAllAndFree(unsigned int size, char *msg, ComlibInstanceHandle cinst) {
156   CkpvAccess(conv_com_object).insertMessage(new MessageHolder(msg, size), cinst);
157 }
158
159 /// In this case the array "pes" is lost by the application together with "msg".
160 inline void ComlibSyncListSendAndFree(int npes, int *pes, unsigned int size, char *msg, ComlibInstanceHandle cinst) {
161   CkpvAccess(conv_com_object).insertMessage(new MessageHolder(msg, size, npes, pes), cinst);
162 }
163
164 inline void ComlibBegin(ComlibInstanceHandle cinst, int iteration) {
165   // Do nothing?
166 }
167
168 inline void ComlibEnd(ComlibInstanceHandle cinst, int iteration) {
169   // flush strategy???
170   CkpvAccess(conv_com_ptr)->doneInserting(cinst);
171 }
172
173 CkpvExtern(int, comlib_handler);
174
175 /* DEPRECATED!!! gained the syntax above similar to Cmi
176 // Send a converse message to a remote strategy instance. On being
177 // received the handleMessage method will be invoked.
178 inline void ConvComlibSendMessage(int instance, int dest_pe, int size, char *msg) {
179   CmiSetHandler(msg, CkpvAccess(strategy_handlerid));
180   ((CmiMsgHeaderBasic *) msg)->stratid = instance;
181     
182   CmiSyncSendAndFree(dest_pe, size, msg);
183 }*/
184
185 /*@}*/
186
187 #endif