still some bugs...but stall site code generation is in
[IRC.git] / Robust / src / Runtime / mlp_runtime.h
1 #ifndef __MLP_RUNTIME__
2 #define __MLP_RUNTIME__
3
4
5 #include <pthread.h>
6 #include "Queue.h"
7 #include "psemaphore.h"
8 #include "mlp_lock.h"
9 #include "memPool.h"
10
11 #ifndef FALSE
12 #define FALSE 0
13 #endif
14
15 #ifndef TRUE
16 #define TRUE 1
17 #endif
18
19 #define NUMBINS 128
20 #define NUMREAD 64
21 #define NUMITEMS 64
22 #define NUMRENTRY 256
23
24 #define READY 1
25 #define NOTREADY 0
26
27 #define READ 0
28 #define WRITE 1
29 #define PARENTREAD 2
30 #define PARENTWRITE 3
31 #define COARSE 4
32 #define PARENTCOARSE 5
33 #define SCCITEM 6
34
35 #define HASHTABLE 0
36 #define VECTOR 1
37 #define SINGLEITEM 2
38
39 #define READBIN 0
40 #define WRITEBIN 1
41
42 #define H_MASK (NUMBINS)-1
43
44 #ifndef FALSE
45 #define FALSE 0
46 #endif
47
48 #ifndef TRUE
49 #define TRUE 1
50 #endif
51
52
53 // these are useful for interpreting an INTPTR to an
54 // Object at runtime to retrieve the object's type
55 // or object id (OID), 64-bit safe
56 #define OBJPTRPTR_2_OBJTYPE( opp ) ((int*)(*(opp)))[0]
57 #define OBJPTRPTR_2_OBJOID(  opp ) ((int*)(*(opp)))[1]
58
59
60
61 // forwarding list elements is a linked
62 // structure of arrays, should help task
63 // dispatch because the first element is
64 // an embedded member of the task record,
65 // only have to do memory allocation if
66 // a lot of items are on the list
67 #define FLIST_ITEMS_PER_ELEMENT 30
68 typedef struct ForwardingListElement_t {
69   int                             numItems;
70   struct ForwardingListElement_t* nextElement;
71   INTPTR                          items[FLIST_ITEMS_PER_ELEMENT];
72 } ForwardingListElement;
73
74
75
76 // these fields are common to any SESE, and casting the
77 // generated SESE record to this can be used, because
78 // the common structure is always the first item in a
79 // customized SESE record
80 typedef struct SESEcommon_t {  
81
82   // the identifier for the class of sese's that
83   // are instances of one particular static code block
84   // IMPORTANT: the class ID must be the first field of
85   // the task record so task dispatch works correctly!
86   int classID;
87
88
89   // a parent waits on this semaphore when stalling on
90   // this child, the child gives it at its SESE exit
91   psemaphore* parentsStallSem;
92
93   
94   // the lock guards the following data SESE's
95   // use to coordinate with one another
96   pthread_mutex_t lock;
97
98   // NOTE: first element is embedded in the task
99   // record, so don't free it!
100   //ForwardingListElement forwardList;
101   struct Queue* forwardList;
102
103
104   volatile int    unresolvedDependencies;
105
106   pthread_cond_t  doneCond;
107   int             doneExecuting;
108
109   pthread_cond_t  runningChildrenCond;
110   int             numRunningChildren;
111
112   struct SESEcommon_t*   parent;
113   
114   int numMemoryQueue;
115   int rentryIdx;
116   int unresolvedRentryIdx;
117   struct MemoryQueue_t** memoryQueueArray;
118   struct REntry_t* rentryArray[NUMRENTRY];
119   struct REntry_t* unresolvedRentryArray[NUMRENTRY];
120
121   int numDependentSESErecords;
122   int offsetToDepSESErecords;
123 #ifdef RCR
124   int offsetToParamRecords;
125 #endif
126
127   // for determining when task records can be returned
128   // to the parent record's memory pool
129   MemPool*     taskRecordMemPool;
130   volatile int refCount;
131 } SESEcommon;
132
133 // a thread-local var refers to the currently
134 // running task
135 extern __thread SESEcommon* runningSESE;
136
137 // there only needs to be one stall semaphore
138 // per thread, just give a reference to it to
139 // the task you are about to block on
140 extern __thread psemaphore runningSESEstallSem;
141
142
143
144 typedef struct REntry_t{
145   // fine read:0, fine write:1, parent read:2, 
146   // parent write:3 coarse: 4, parent coarse:5, scc: 6
147   int type;
148   struct Hashtable_t* hashtable;
149   struct BinItem_t* binitem;
150   struct Vector_t* vector;
151   struct SCC_t* scc;
152   struct MemoryQueue_t* queue;
153   psemaphore parentStallSem;
154   int tag;
155   SESEcommon* seseRec;
156   INTPTR* pointer;
157   int isBufMode;
158 } REntry;
159
160 typedef struct MemoryQueueItem_t {
161   int type; // hashtable:0, vector:1, singleitem:2
162   int total;        //total non-retired
163   int status;       //NOTREADY, READY
164   struct MemoryQueueItem_t *next; 
165 } MemoryQueueItem;
166
167 typedef struct MemoryQueue_t {
168   MemoryQueueItem * head;
169   MemoryQueueItem * tail;  
170   REntry * binbuf[NUMBINS];
171   REntry * buf[NUMRENTRY];
172   int bufcount;
173 } MemoryQueue;
174
175 typedef struct BinItem_t {
176   int total;
177   int status;       //NOTREADY, READY
178   int type;         //READBIN:0, WRITEBIN:1
179   struct BinItem_t * next;
180 } BinItem;
181
182 typedef struct Hashtable_t {
183   MemoryQueueItem item;
184   struct BinElement_t* array[NUMBINS];
185   struct Queue*   unresolvedQueue;
186 } Hashtable;
187
188 typedef struct BinElement_t {
189   BinItem * head;
190   BinItem * tail;
191 } BinElement;
192
193 typedef struct WriteBinItem_t {
194   BinItem item;
195   REntry * val;
196 } WriteBinItem;
197
198 typedef struct ReadBinItem_t {
199   BinItem item;
200   REntry * array[NUMREAD];
201   int index;
202 } ReadBinItem;
203
204 typedef struct Vector_t {
205   MemoryQueueItem item;
206   REntry * array[NUMITEMS];
207   int index;
208 } Vector;
209
210 typedef struct SCC_t {
211   MemoryQueueItem item;
212   REntry * val;
213 } SCC;
214
215 int ADDRENTRY(MemoryQueue* q, REntry * r);
216 void RETIRERENTRY(MemoryQueue* Q, REntry * r);
217
218
219
220
221 static inline void ADD_FORWARD_ITEM( ForwardingListElement* e,
222                                      SESEcommon*            s ) {
223   //atomic_inc( &(s->refCount) );
224 }
225
226
227
228
229 // simple mechanical allocation and 
230 // deallocation of SESE records
231 void* mlpAllocSESErecord( int size );
232 void  mlpFreeSESErecord( SESEcommon* seseRecord );
233
234 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue);
235 REntry* mlpCreateFineREntry(int type, SESEcommon* seseToIssue, void* dynID);
236 REntry* mlpCreateREntry    (int type, SESEcommon* seseToIssue);
237 MemoryQueue* createMemoryQueue();
238 void rehashMemoryQueue(SESEcommon* seseParent);
239
240
241 static inline void ADD_REFERENCE_TO( SESEcommon* seseRec ) {
242   atomic_inc( &(seseRec->refCount) );
243 }
244
245 static inline void RELEASE_REFERENCE_TO( SESEcommon* seseRec ) {
246   if( atomic_sub_and_test( 1, &(seseRec->refCount) ) ) {
247     poolfreeinto( seseRec->parent->taskRecordMemPool, seseRec );
248   }
249 }
250
251
252 #endif /* __MLP_RUNTIME__ */