#include "Queue.h"
#include "psemaphore.h"
#include "mlp_lock.h"
+#include "memPool.h"
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
+
+#define OBJPTRPTR_2_OBJTYPE( opp ) ((int*)(*(opp)))[0]
+#define OBJPTRPTR_2_OBJOID( opp ) ((int*)(*(opp)))[1]
+
+
+
+// these fields are common to any SESE, and casting the
+// generated SESE record to this can be used, because
+// the common structure is always the first item in a
+// customized SESE record
+typedef struct SESEcommon_t {
+
+ // the identifier for the class of sese's that
+ // are instances of one particular static code block
+ // IMPORTANT: the class ID must be the first field of
+ // the task record so task dispatch works correctly!
+ int classID;
+
+ // a parent waits on this semaphore when stalling on
+ // this child, the child gives it at its SESE exit
+ psemaphore stallSem;
+
+
+ // the lock guards the following data SESE's
+ // use to coordinate with one another
+ pthread_mutex_t lock;
+
+ struct Queue* forwardList;
+ volatile int unresolvedDependencies;
+
+ pthread_cond_t doneCond;
+ int doneExecuting;
+
+ pthread_cond_t runningChildrenCond;
+ int numRunningChildren;
+
+ struct SESEcommon_t* parent;
+
+ psemaphore parentStallSem;
+ pthread_cond_t stallDone;
+
+ int numMemoryQueue;
+ int rentryIdx;
+ int unresolvedRentryIdx;
+ struct MemoryQueue_t** memoryQueueArray;
+ struct REntry_t* rentryArray[NUMRENTRY];
+ struct REntry_t* unresolvedRentryArray[NUMRENTRY];
+
+ int numDependentSESErecords;
+ int offsetToDepSESErecords;
+
+ // for determining when task records can be returned
+ // to the parent record's memory pool
+ MemPool* taskRecordMemPool;
+ volatile int refCount;
+
+} SESEcommon;
+
+
+// a thread-local var refers to the currently
+// running task
+extern __thread SESEcommon* runningSESE;
+
+
+
typedef struct REntry_t{
int type; // fine read:0, fine write:1, parent read:2, parent write:3 coarse: 4, parent coarse:5, scc: 6
struct Hashtable_t* hashtable;
struct SCC_t* scc;
struct MemoryQueue_t* queue;
psemaphore parentStallSem;
- void* seseRec;
- void* dynID;
+ SESEcommon* seseRec;
+ INTPTR* pointer;
+ int isBufMode;
} REntry;
typedef struct MemoryQueueItem_t {
int type; // hashtable:0, vector:1, singleitem:2
int total; //total non-retired
int status; //NOTREADY, READY
- struct MemoryQueueItem_t *next;
+ struct MemoryQueueItem_t *next;
} MemoryQueueItem;
typedef struct MemoryQueue_t {
MemoryQueueItem * head;
MemoryQueueItem * tail;
+ REntry * binbuf[NUMBINS];
+ REntry * buf[NUMRENTRY];
+ int bufcount;
} MemoryQueue;
typedef struct BinItem_t {
typedef struct Hashtable_t {
MemoryQueueItem item;
struct BinElement_t* array[NUMBINS];
+ struct Queue* unresolvedQueue;
} Hashtable;
typedef struct BinElement_t {
void RETIRERENTRY(MemoryQueue* Q, REntry * r);
-// forward declaration of pointer type
-typedef struct SESEcommon_t* SESEcommon_p;
-
-// these fields are common to any SESE, and casting the
-// generated SESE record to this can be used, because
-// the common structure is always the first item in a
-// customized SESE record
-typedef struct SESEcommon_t {
-
- // the identifier for the class of sese's that
- // are instances of one particular static code block
- int classID;
-
- // a parent waits on this semaphore when stalling on
- // this child, the child gives it at its SESE exit
- psemaphore stallSem;
-
-
- // the lock guards the following data SESE's
- // use to coordinate with one another
- pthread_mutex_t lock;
-
- struct Queue* forwardList;
- volatile int unresolvedDependencies;
-
- pthread_cond_t doneCond;
- int doneExecuting;
-
- pthread_cond_t runningChildrenCond;
- int numRunningChildren;
-
- SESEcommon_p parent;
-
- psemaphore parentStallSem;
- pthread_cond_t stallDone;
-
- int numMemoryQueue;
- int rentryIdx;
- struct MemoryQueue_t** memoryQueueArray;
- struct REntry_t* rentryArray[NUMRENTRY];
-
-} SESEcommon;
-
-// a thread-local stack of SESEs and function to
-// ensure it is initialized once per thread
-/*
-extern __thread struct Queue* seseCallStack;
-extern __thread pthread_once_t mlpOnceObj;
-void mlpInitOncePerThread();
-*/
-extern __thread SESEcommon_p seseCaller;
-
// simple mechanical allocation and
// deallocation of SESE records
-void* mlpCreateSESErecord( int size );
-void mlpDestroySESErecord( void* seseRecord );
void* mlpAllocSESErecord( int size );
+void mlpFreeSESErecord( SESEcommon* seseRecord );
MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue);
-REntry* mlpCreateFineREntry(int type, void* seseToIssue, void* dynID);
-REntry* mlpCreateREntry(int type, void* seseToIssue);
+REntry* mlpCreateFineREntry(int type, SESEcommon* seseToIssue, void* dynID);
+REntry* mlpCreateREntry (int type, SESEcommon* seseToIssue);
MemoryQueue* createMemoryQueue();
+void rehashMemoryQueue(SESEcommon* seseParent);
+
+
+static inline void ADD_REFERENCE_TO( SESEcommon* seseRec ) {
+#ifndef OOO_DISABLE_TASKMEMPOOL
+ atomic_inc( &(seseRec->refCount) );
+#endif
+}
+
+static inline void RELEASE_REFERENCE_TO( SESEcommon* seseRec ) {
+#ifndef OOO_DISABLE_TASKMEMPOOL
+ if( atomic_sub_and_test( 1, &(seseRec->refCount) ) ) {
+ poolfreeinto( seseRec->parent->taskRecordMemPool, seseRec );
+ }
+#endif
+}
+
#endif /* __MLP_RUNTIME__ */