1 #ifndef __MLP_RUNTIME__
2 #define __MLP_RUNTIME__
7 #include "psemaphore.h"
32 #define PARENTCOARSE 5
42 #define H_MASK (NUMBINS)-1
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]
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 {
70 struct ForwardingListElement_t* nextElement;
71 INTPTR items[FLIST_ITEMS_PER_ELEMENT];
72 } ForwardingListElement;
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 {
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!
89 // a parent waits on this semaphore when stalling on
90 // this child, the child gives it at its SESE exit
91 psemaphore* parentsStallSem;
94 // the lock guards the following data SESE's
95 // use to coordinate with one another
98 // NOTE: first element is embedded in the task
99 // record, so don't free it!
100 //ForwardingListElement forwardList;
101 struct Queue* forwardList;
104 volatile int unresolvedDependencies;
106 pthread_cond_t doneCond;
109 pthread_cond_t runningChildrenCond;
110 int numRunningChildren;
112 struct SESEcommon_t* parent;
116 int unresolvedRentryIdx;
117 struct MemoryQueue_t** memoryQueueArray;
118 struct REntry_t* rentryArray[NUMRENTRY];
119 struct REntry_t* unresolvedRentryArray[NUMRENTRY];
121 int numDependentSESErecords;
122 int offsetToDepSESErecords;
124 int offsetToParamRecords;
127 // for determining when task records can be returned
128 // to the parent record's memory pool
129 MemPool* taskRecordMemPool;
130 volatile int refCount;
133 // a thread-local var refers to the currently
135 extern __thread SESEcommon* runningSESE;
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;
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
148 struct Hashtable_t* hashtable;
149 struct BinItem_t* binitem;
150 struct Vector_t* vector;
152 struct MemoryQueue_t* queue;
153 psemaphore parentStallSem;
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;
167 typedef struct MemoryQueue_t {
168 MemoryQueueItem * head;
169 MemoryQueueItem * tail;
170 REntry * binbuf[NUMBINS];
171 REntry * buf[NUMRENTRY];
175 typedef struct BinItem_t {
177 int status; //NOTREADY, READY
178 int type; //READBIN:0, WRITEBIN:1
179 struct BinItem_t * next;
182 typedef struct Hashtable_t {
183 MemoryQueueItem item;
184 struct BinElement_t* array[NUMBINS];
185 struct Queue* unresolvedQueue;
188 typedef struct BinElement_t {
193 typedef struct WriteBinItem_t {
198 typedef struct ReadBinItem_t {
200 REntry * array[NUMREAD];
204 typedef struct Vector_t {
205 MemoryQueueItem item;
206 REntry * array[NUMITEMS];
210 typedef struct SCC_t {
211 MemoryQueueItem item;
215 int ADDRENTRY(MemoryQueue* q, REntry * r);
216 void RETIRERENTRY(MemoryQueue* Q, REntry * r);
221 static inline void ADD_FORWARD_ITEM( ForwardingListElement* e,
223 //atomic_inc( &(s->refCount) );
229 // simple mechanical allocation and
230 // deallocation of SESE records
231 void* mlpAllocSESErecord( int size );
232 void mlpFreeSESErecord( SESEcommon* seseRecord );
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);
241 static inline void ADD_REFERENCE_TO( SESEcommon* seseRec ) {
242 atomic_inc( &(seseRec->refCount) );
245 static inline void RELEASE_REFERENCE_TO( SESEcommon* seseRec ) {
246 if( atomic_sub_and_test( 1, &(seseRec->refCount) ) ) {
247 poolfreeinto( seseRec->parent->taskRecordMemPool, seseRec );
252 #endif /* __MLP_RUNTIME__ */