1 #ifndef __MLP_RUNTIME__
2 #define __MLP_RUNTIME__
9 #include "psemaphore.h"
34 #define PARENTCOARSE 5
44 #define H_MASK (NUMBINS)-1
55 // these are useful for interpreting an INTPTR to an
56 // Object at runtime to retrieve the object's type
57 // or object id (OID), 64-bit safe
58 #define OBJPTRPTR_2_OBJTYPE( opp ) ((int*)(opp))[0]
59 #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!
87 volatile int unresolvedDependencies;
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 // NOTE: first element is embedded in the task
95 // record, so don't free it!
96 //ForwardingListElement forwardList;
97 struct Queue forwardList;
99 volatile int doneExecuting;
100 volatile int numRunningChildren;
102 struct SESEcommon_t* parent;
106 int unresolvedRentryIdx;
107 volatile int refCount;
108 int numDependentSESErecords;
109 int offsetToDepSESErecords;
110 struct MemPool_t * taskRecordMemPool;
112 struct MemoryQueue_t** memoryQueueArray;
113 struct REntry_t* rentryArray[NUMRENTRY];
114 struct REntry_t* unresolvedRentryArray[NUMRENTRY];
118 int offsetToParamRecords;
119 volatile int rcrstatus;
120 volatile int retired;
123 // the lock guards the following data SESE's
124 // use to coordinate with one another
125 pthread_mutex_t lock;
126 pthread_cond_t runningChildrenCond;
129 // a thread-local var refers to the currently
131 extern __thread SESEcommon* runningSESE;
132 extern __thread int childSESE;
134 // there only needs to be one stall semaphore
135 // per thread, just give a reference to it to
136 // the task you are about to block on
137 extern __thread psemaphore runningSESEstallSem;
141 typedef struct REntry_t{
142 // fine read:0, fine write:1, parent read:2,
143 // parent write:3 coarse: 4, parent coarse:5, scc: 6
145 struct Hashtable_t* hashtable;
146 struct BinItem_t* binitem;
147 struct Vector_t* vector;
149 struct MemoryQueue_t* queue;
150 psemaphore * parentStallSem;
159 #define RUNBIAS 1000000
166 void * ptrarray[RCRSIZE];
167 struct rcrRecord *next;
170 typedef struct SESEstall_t {
174 struct ___Object___* ___obj___;
175 struct rcrRecord rcrRecords[1];
180 typedef struct MemoryQueueItem_t {
181 int type; // hashtable:0, vector:1, singleitem:2
182 int total; //total non-retired
183 int status; //NOTREADY, READY
184 struct MemoryQueueItem_t *next;
188 typedef struct MemoryQueue_t {
189 MemoryQueueItem * head;
190 MemoryQueueItem * tail;
191 REntry * binbuf[NUMBINS];
192 REntry * buf[NUMRENTRY];
194 #ifndef OOO_DISABLE_TASKMEMPOOL
195 MemPool * rentrypool;
199 typedef struct BinItem_t {
201 int status; //NOTREADY, READY
202 int type; //READBIN:0, WRITEBIN:1
203 struct BinItem_t * next;
206 typedef struct Hashtable_t {
207 MemoryQueueItem item;
208 struct BinElement_t* array[NUMBINS];
209 struct Queue* unresolvedQueue;
212 typedef struct BinElement_t {
217 typedef struct WriteBinItem_t {
222 typedef struct ReadBinItem_t {
224 REntry * array[NUMREAD];
228 typedef struct Vector_t {
229 MemoryQueueItem item;
230 REntry * array[NUMITEMS];
234 typedef struct SCC_t {
235 MemoryQueueItem item;
239 int ADDRENTRY(MemoryQueue* q, REntry * r);
240 void RETIRERENTRY(MemoryQueue* Q, REntry * r);
245 static inline void ADD_FORWARD_ITEM( ForwardingListElement* e,
247 //atomic_inc( &(s->refCount) );
253 // simple mechanical allocation and
254 // deallocation of SESE records
255 void* mlpAllocSESErecord( int size );
256 void mlpFreeSESErecord( SESEcommon* seseRecord );
258 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue);
259 REntry* mlpCreateFineREntry(MemoryQueue *q, int type, SESEcommon* seseToIssue, void* dynID);
260 REntry* mlpCreateREntry(MemoryQueue *q, int type, SESEcommon* seseToIssue);
261 MemoryQueue* createMemoryQueue();
262 void rehashMemoryQueue(SESEcommon* seseParent);
265 static inline void ADD_REFERENCE_TO( SESEcommon* seseRec ) {
266 atomic_inc( &(seseRec->refCount) );
269 static inline void RELEASE_REFERENCE_TO( SESEcommon* seseRec ) {
270 if( atomic_sub_and_test( 1, &(seseRec->refCount) ) ) {
271 poolfreeinto( seseRec->parent->taskRecordMemPool, seseRec );
276 // this is for using a memPool to allocate task records,
277 // pass this into the poolcreate so it will run your
278 // custom init code ONLY for fresh records, reused records
279 // can be returned as is
280 void freshTaskRecordInitializer( void* seseRecord );
283 #endif /* __MLP_RUNTIME__ */