changes
[IRC.git] / Robust / src / Runtime / mlp_runtime.h
index 520a7d21fc8e230db0e4b0bc24a4ff8116c1c74d..ec0715b600ff355517bc22ba41d6b571c55b3fc9 100644 (file)
@@ -2,12 +2,20 @@
 #define __MLP_RUNTIME__
 
 
+#include <stdlib.h>
+#include <stdio.h>
+
+
 #include <pthread.h>
+#include "runtime.h"
+#include "mem.h"
 #include "Queue.h"
 #include "psemaphore.h"
 #include "mlp_lock.h"
 #include "memPool.h"
 
+
+
 #ifndef FALSE
 #define FALSE 0
 #endif
 // these are useful for interpreting an INTPTR to an
 // Object at runtime to retrieve the object's type
 // or object id (OID), 64-bit safe
-#define OBJPTRPTR_2_OBJTYPE( opp ) ((int*)(opp))[0]
-#define OBJPTRPTR_2_OBJOID(  opp ) ((int*)(opp))[1]
-
-
+#define OBJPTRPTR_2_OBJTYPE( opp ) ((int*)*(opp))[0]
+#define OBJPTRPTR_2_OBJOID(  opp ) ((int*)*(opp))[1]
 
 // forwarding list elements is a linked
 // structure of arrays, should help task
@@ -71,7 +77,7 @@ typedef struct ForwardingListElement_t {
   INTPTR                          items[FLIST_ITEMS_PER_ELEMENT];
 } ForwardingListElement;
 
-
+struct MemPool_t;
 
 // these fields are common to any SESE, and casting the
 // generated SESE record to this can be used, because
@@ -84,56 +90,51 @@ typedef struct SESEcommon_t {
   // IMPORTANT: the class ID must be the first field of
   // the task record so task dispatch works correctly!
   int classID;
-
+  volatile int    unresolvedDependencies;
 
   // a parent waits on this semaphore when stalling on
   // this child, the child gives it at its SESE exit
   psemaphore* parentsStallSem;
 
   
-  // the lock guards the following data SESE's
-  // use to coordinate with one another
-  pthread_mutex_t lock;
-
   // NOTE: first element is embedded in the task
   // record, so don't free it!
   //ForwardingListElement forwardList;
-  struct Queue* forwardList;
+  struct Queue forwardList;
 
-  volatile int    unresolvedDependencies;
-
-  pthread_cond_t  doneCond;
   volatile int             doneExecuting;
-
-  pthread_cond_t  runningChildrenCond;
-  int             numRunningChildren;
+  volatile int             numRunningChildren;
 
   struct SESEcommon_t*   parent;
   
   int numMemoryQueue;
   int rentryIdx;
   int unresolvedRentryIdx;
+  volatile int refCount;
+  int numDependentSESErecords;
+  int offsetToDepSESErecords;
+  struct MemPool_t *     taskRecordMemPool;
+
   struct MemoryQueue_t** memoryQueueArray;
   struct REntry_t* rentryArray[NUMRENTRY];
   struct REntry_t* unresolvedRentryArray[NUMRENTRY];
 
-  int numDependentSESErecords;
-  int offsetToDepSESErecords;
 #ifdef RCR
   int offsetToParamRecords;
   volatile int rcrstatus;
   volatile int retired;
 #endif
 
-  // for determining when task records can be returned
-  // to the parent record's memory pool
-  MemPool*     taskRecordMemPool;
-  volatile int refCount;
+  // the lock guards the following data SESE's
+  // use to coordinate with one another
+  pthread_mutex_t lock;
+  pthread_cond_t  runningChildrenCond;
 } SESEcommon;
 
 // a thread-local var refers to the currently
 // running task
 extern __thread SESEcommon* runningSESE;
+extern __thread int childSESE;
 
 // there only needs to be one stall semaphore
 // per thread, just give a reference to it to
@@ -146,15 +147,16 @@ typedef struct REntry_t{
   // fine read:0, fine write:1, parent read:2, 
   // parent write:3 coarse: 4, parent coarse:5, scc: 6
   int type;
-  struct Hashtable_t* hashtable;
+  int tag;
+  MemoryQueueItem *qitem;
   struct BinItem_t* binitem;
-  struct Vector_t* vector;
-  struct SCC_t* scc;
   struct MemoryQueue_t* queue;
-  psemaphore parentStallSem;
-  int tag;
   SESEcommon* seseRec;
   INTPTR* pointer;
+  psemaphore * parentStallSem;
+#ifdef RCR
+  INTPTR mask;
+#endif
   int isBufMode;
 } REntry;
 
@@ -185,7 +187,8 @@ 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 {
@@ -194,6 +197,9 @@ typedef struct MemoryQueue_t {
   REntry * binbuf[NUMBINS];
   REntry * buf[NUMRENTRY];
   int bufcount;
+#ifndef OOO_DISABLE_TASKMEMPOOL
+  MemPool * rentrypool;
+#endif
 } MemoryQueue;
 
 typedef struct BinItem_t {
@@ -247,30 +253,64 @@ static inline void ADD_FORWARD_ITEM( ForwardingListElement* e,
   //atomic_inc( &(s->refCount) );
 }
 
-
-
-
 // simple mechanical allocation and 
 // deallocation of SESE records
 void* mlpAllocSESErecord( int size );
 void  mlpFreeSESErecord( SESEcommon* seseRecord );
 
 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue);
-REntry* mlpCreateFineREntry(int type, SESEcommon* seseToIssue, void* dynID);
-REntry* mlpCreateREntry    (int type, SESEcommon* seseToIssue);
+REntry* mlpCreateFineREntry(MemoryQueue *q, int type, SESEcommon* seseToIssue, void* dynID);
+#ifdef RCR
+REntry* mlpCreateREntry(MemoryQueue *q, int type, SESEcommon* seseToIssue, INTPTR mask);
+#else
+REntry* mlpCreateREntry(MemoryQueue *q, int type, SESEcommon* seseToIssue);
+#endif
 MemoryQueue* createMemoryQueue();
 void rehashMemoryQueue(SESEcommon* seseParent);
 
-
 static inline void ADD_REFERENCE_TO( SESEcommon* seseRec ) {
   atomic_inc( &(seseRec->refCount) );
 }
 
-static inline void RELEASE_REFERENCE_TO( SESEcommon* seseRec ) {
+static inline int RELEASE_REFERENCE_TO( SESEcommon* seseRec ) {
   if( atomic_sub_and_test( 1, &(seseRec->refCount) ) ) {
     poolfreeinto( seseRec->parent->taskRecordMemPool, seseRec );
+    return 1;
   }
+  return 0;
+}
+
+#define CHECK_RECORD(x) ;
+
+
+////////////////////////////////////////////////
+// 
+//  Some available debug versions of the above
+//  pool allocation-related helpers.  The lower
+//  'x' appended to names means they are not hooked
+//  up, but check em in so we can switch names and
+//  use them for debugging
+//
+////////////////////////////////////////////////
+#define ADD_REFERENCE_TOx(x) atomic_inc( &((x)->refCount) ); printf("0x%x ADD 0x%x on %d\n",(INTPTR)runningSESE,(INTPTR)(x),__LINE__);
+
+#define RELEASE_REFERENCE_TOx(x) if (atomic_sub_and_test(1, &((x)->refCount))) {poolfreeinto(x->parent->taskRecordMemPool, x);printf("0x%x REL 0x%x on %d\n",(INTPTR)runningSESE,(INTPTR)(x),__LINE__);}
+
+#define CHECK_RECORDx(x) { \
+  if( ((SESEcommon*)(x))->refCount != 0 ) {                             \
+    printf( "Acquired 0x%x from poolalloc, with refCount=%d\n", (INTPTR)(x), ((SESEcommon*)(x))->refCount ); } \
+  if( ((SESEcommon*)(x))->fresh != 1 ) {                              \
+    printf("0x%x reclaimed 0x%x on %d\n",(INTPTR)runningSESE,(INTPTR)(x),__LINE__); } \
+  ((SESEcommon*)(x))->fresh = 0; \
 }
 
 
+
+// this is for using a memPool to allocate task records,
+// pass this into the poolcreate so it will run your
+// custom init code ONLY for fresh records, reused records
+// can be returned as is
+void freshTaskRecordInitializer( void* seseRecord );
+  
+
 #endif /* __MLP_RUNTIME__ */