6a2972ea1cb44d24af1dabe3076c0b3cdac7205e
[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 64
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<<4)-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   // a parent waits on this semaphore when stalling on
89   // this child, the child gives it at its SESE exit
90   psemaphore stallSem;
91
92   
93   // the lock guards the following data SESE's
94   // use to coordinate with one another
95   pthread_mutex_t lock;
96
97   // NOTE: first element is embedded in the task
98   // record, so don't free it!
99   //ForwardingListElement forwardList;
100   struct Queue* forwardList;
101
102
103   volatile int    unresolvedDependencies;
104
105   pthread_cond_t  doneCond;
106   int             doneExecuting;
107
108   pthread_cond_t  runningChildrenCond;
109   int             numRunningChildren;
110
111   struct SESEcommon_t*   parent;
112
113   //psemaphore parentStallSem;
114   //pthread_cond_t stallDone;
115
116   int numMemoryQueue;
117   int rentryIdx;
118   int unresolvedRentryIdx;
119   struct MemoryQueue_t** memoryQueueArray;
120   struct REntry_t* rentryArray[NUMRENTRY];
121   struct REntry_t* unresolvedRentryArray[NUMRENTRY];
122
123   int numDependentSESErecords;
124   int offsetToDepSESErecords;
125
126   // for determining when task records can be returned
127   // to the parent record's memory pool
128   MemPool*     taskRecordMemPool;
129   volatile int refCount;
130
131 } SESEcommon;
132
133
134 // a thread-local var refers to the currently
135 // running task
136 extern __thread SESEcommon* runningSESE;
137
138
139
140 typedef struct REntry_t{
141   // fine read:0, fine write:1, parent read:2, 
142   // parent write:3 coarse: 4, parent coarse:5, scc: 6
143   int type;
144   struct Hashtable_t* hashtable;
145   struct BinItem_t* binitem;
146   struct Vector_t* vector;
147   struct SCC_t* scc;
148   struct MemoryQueue_t* queue;
149   psemaphore parentStallSem;
150   SESEcommon* seseRec;
151   INTPTR* pointer;
152   int isBufMode;
153 } REntry;
154
155 typedef struct MemoryQueueItem_t {
156   int type; // hashtable:0, vector:1, singleitem:2
157   int total;        //total non-retired
158   int status;       //NOTREADY, READY
159   struct MemoryQueueItem_t *next; 
160 } MemoryQueueItem;
161
162 typedef struct MemoryQueue_t {
163   MemoryQueueItem * head;
164   MemoryQueueItem * tail;  
165   REntry * binbuf[NUMBINS];
166   REntry * buf[NUMRENTRY];
167   int bufcount;
168 } MemoryQueue;
169
170 typedef struct BinItem_t {
171   int total;
172   int status;       //NOTREADY, READY
173   int type;         //READBIN:0, WRITEBIN:1
174   struct BinItem_t * next;
175 } BinItem;
176
177 typedef struct Hashtable_t {
178   MemoryQueueItem item;
179   struct BinElement_t* array[NUMBINS];
180   struct Queue*   unresolvedQueue;
181 } Hashtable;
182
183 typedef struct BinElement_t {
184   BinItem * head;
185   BinItem * tail;
186 } BinElement;
187
188 typedef struct WriteBinItem_t {
189   BinItem item;
190   REntry * val;
191 } WriteBinItem;
192
193 typedef struct ReadBinItem_t {
194   BinItem item;
195   REntry * array[NUMREAD];
196   int index;
197 } ReadBinItem;
198
199 typedef struct Vector_t {
200   MemoryQueueItem item;
201   REntry * array[NUMITEMS];
202   int index;
203 } Vector;
204
205 typedef struct SCC_t {
206   MemoryQueueItem item;
207   REntry * val;
208 } SCC;
209
210 int ADDRENTRY(MemoryQueue* q, REntry * r);
211 void RETIRERENTRY(MemoryQueue* Q, REntry * r);
212
213
214
215
216 static inline void ADD_FORWARD_ITEM( ForwardingListElement* e,
217                                      SESEcommon*            s ) {
218   //atomic_inc( &(s->refCount) );
219 }
220
221
222
223
224 // simple mechanical allocation and 
225 // deallocation of SESE records
226 void* mlpAllocSESErecord( int size );
227 void  mlpFreeSESErecord( SESEcommon* seseRecord );
228
229 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue);
230 REntry* mlpCreateFineREntry(int type, SESEcommon* seseToIssue, void* dynID);
231 REntry* mlpCreateREntry    (int type, SESEcommon* seseToIssue);
232 MemoryQueue* createMemoryQueue();
233 void rehashMemoryQueue(SESEcommon* seseParent);
234
235
236 static inline void ADD_REFERENCE_TO( SESEcommon* seseRec ) {
237   atomic_inc( &(seseRec->refCount) );
238 }
239
240 static inline void RELEASE_REFERENCE_TO( SESEcommon* seseRec ) {
241   if( atomic_sub_and_test( 1, &(seseRec->refCount) ) ) {
242     poolfreeinto( seseRec->parent->taskRecordMemPool, seseRec );
243   }
244 }
245
246
247 #endif /* __MLP_RUNTIME__ */