working on task mem pool, there is a crash bug, use -ooodebug-disable-task-mem-pool...
[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 #define OBJPTRPTR_2_OBJTYPE( opp ) ((int*)(*(opp)))[0]
54 #define OBJPTRPTR_2_OBJOID(  opp ) ((int*)(*(opp)))[1]
55
56
57
58 // these fields are common to any SESE, and casting the
59 // generated SESE record to this can be used, because
60 // the common structure is always the first item in a
61 // customized SESE record
62 typedef struct SESEcommon_t {  
63
64   // the identifier for the class of sese's that
65   // are instances of one particular static code block
66   // IMPORTANT: the class ID must be the first field of
67   // the task record so task dispatch works correctly!
68   int classID;
69
70   // a parent waits on this semaphore when stalling on
71   // this child, the child gives it at its SESE exit
72   psemaphore stallSem;
73
74   
75   // the lock guards the following data SESE's
76   // use to coordinate with one another
77   pthread_mutex_t lock;
78
79   struct Queue*   forwardList;
80   volatile int    unresolvedDependencies;
81
82   pthread_cond_t  doneCond;
83   int             doneExecuting;
84
85   pthread_cond_t  runningChildrenCond;
86   int             numRunningChildren;
87
88   struct SESEcommon_t*   parent;
89
90   psemaphore parentStallSem;
91   pthread_cond_t stallDone;
92
93   int numMemoryQueue;
94   int rentryIdx;
95   int unresolvedRentryIdx;
96   struct MemoryQueue_t** memoryQueueArray;
97   struct REntry_t* rentryArray[NUMRENTRY];
98   struct REntry_t* unresolvedRentryArray[NUMRENTRY];
99
100   int numDependentSESErecords;
101   int offsetToDepSESErecords;
102
103   // for determining when task records can be returned
104   // to the parent record's memory pool
105   MemPool*     taskRecordMemPool;
106   volatile int refCount;
107
108 } SESEcommon;
109
110
111 // a thread-local var refers to the currently
112 // running task
113 extern __thread SESEcommon* runningSESE;
114
115
116
117 typedef struct REntry_t{
118   int type; // fine read:0, fine write:1, parent read:2, parent write:3 coarse: 4, parent coarse:5, scc: 6
119   struct Hashtable_t* hashtable;
120   struct BinItem_t* binitem;
121   struct Vector_t* vector;
122   struct SCC_t* scc;
123   struct MemoryQueue_t* queue;
124   psemaphore parentStallSem;
125   SESEcommon* seseRec;
126   INTPTR* pointer;
127   int isBufMode;
128 } REntry;
129
130 typedef struct MemoryQueueItem_t {
131   int type; // hashtable:0, vector:1, singleitem:2
132   int total;        //total non-retired
133   int status;       //NOTREADY, READY
134   struct MemoryQueueItem_t *next; 
135 } MemoryQueueItem;
136
137 typedef struct MemoryQueue_t {
138   MemoryQueueItem * head;
139   MemoryQueueItem * tail;  
140   REntry * binbuf[NUMBINS];
141   REntry * buf[NUMRENTRY];
142   int bufcount;
143 } MemoryQueue;
144
145 typedef struct BinItem_t {
146   int total;
147   int status;       //NOTREADY, READY
148   int type;         //READBIN:0, WRITEBIN:1
149   struct BinItem_t * next;
150 } BinItem;
151
152 typedef struct Hashtable_t {
153   MemoryQueueItem item;
154   struct BinElement_t* array[NUMBINS];
155   struct Queue*   unresolvedQueue;
156 } Hashtable;
157
158 typedef struct BinElement_t {
159   BinItem * head;
160   BinItem * tail;
161 } BinElement;
162
163 typedef struct WriteBinItem_t {
164   BinItem item;
165   REntry * val;
166 } WriteBinItem;
167
168 typedef struct ReadBinItem_t {
169   BinItem item;
170   REntry * array[NUMREAD];
171   int index;
172 } ReadBinItem;
173
174 typedef struct Vector_t {
175   MemoryQueueItem item;
176   REntry * array[NUMITEMS];
177   int index;
178 } Vector;
179
180 typedef struct SCC_t {
181   MemoryQueueItem item;
182   REntry * val;
183 } SCC;
184
185 int ADDRENTRY(MemoryQueue* q, REntry * r);
186 void RETIRERENTRY(MemoryQueue* Q, REntry * r);
187
188
189
190 // simple mechanical allocation and 
191 // deallocation of SESE records
192 void* mlpAllocSESErecord( int size );
193 void  mlpFreeSESErecord( SESEcommon* seseRecord );
194
195 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue);
196 REntry* mlpCreateFineREntry(int type, SESEcommon* seseToIssue, void* dynID);
197 REntry* mlpCreateREntry    (int type, SESEcommon* seseToIssue);
198 MemoryQueue* createMemoryQueue();
199 void rehashMemoryQueue(SESEcommon* seseParent);
200
201
202 static inline void ADD_REFERENCE_TO( SESEcommon* seseRec ) {
203 #ifndef OOO_DISABLE_TASKMEMPOOL
204   atomic_inc( &(seseRec->refCount) );
205 #endif
206 }
207
208 static inline void RELEASE_REFERENCE_TO( SESEcommon* seseRec ) {
209 #ifndef OOO_DISABLE_TASKMEMPOOL
210   if( atomic_sub_and_test( 1, &(seseRec->refCount) ) ) {
211     poolfreeinto( seseRec->parent->taskRecordMemPool, seseRec );
212   }
213 #endif
214 }
215
216
217 #endif /* __MLP_RUNTIME__ */