working on task mem pool, there is a crash bug, use -ooodebug-disable-task-mem-pool...
[IRC.git] / Robust / src / Runtime / mlp_runtime.h
index 5480ad2f0567bd2a62360e21ef49ec5738bcbf42..4e351a50974a73fac14bffc48908328d3cf24d58 100644 (file)
 #define __MLP_RUNTIME__
 
 
-// value mode means the variable's value
-// is present in the SESEvar struct
-#define SESEvar_MODE_VALUE   3001
-
-// static move means the variable's value
-// will come from a statically known SESE
-#define SESEvar_MODE_STATIC  3002
-
-// dynamic mode means the variable's value
-// will come from an SESE, and the exact
-// SESE will be determined at runtime
-#define SESEvar_MODE_DYNAMIC 3003
-
-
-// a forward delcaration for SESEvar
-struct SESErecord;
-
-
-struct SESEvar {
-  unsigned char mode;
-
-  // the value when it is known will be placed
-  // in this location, which can be accessed
-  // as a variety of types
-  union {
-    char   sesetype_byte;
-    char   sesetype_boolean;
-    short  sesetype_short;
-    int    sesetype_int;
-    long   sesetype_long;
-    char   sesetype_char;
-    float  sesetype_float;
-    double sesetype_double;
-  };
-  
-  // a statically or dynamically known SESE
-  // to gather the variable's value from
-  struct SESErecord* source;
-  unsigned int index;
-};
+#include <pthread.h>
+#include "Queue.h"
+#include "psemaphore.h"
+#include "mlp_lock.h"
+#include "memPool.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#define NUMBINS 64
+#define NUMREAD 64
+#define NUMITEMS 64
+#define NUMRENTRY 256
+
+#define READY 1
+#define NOTREADY 0
+
+#define READ 0
+#define WRITE 1
+#define PARENTREAD 2
+#define PARENTWRITE 3
+#define COARSE 4
+#define PARENTCOARSE 5
+#define SCCITEM 6
+
+#define HASHTABLE 0
+#define VECTOR 1
+#define SINGLEITEM 2
+
+#define READBIN 0
+#define WRITEBIN 1
+
+#define H_MASK (NUMBINS<<4)-1
 
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#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 {  
 
-struct SESErecord {  
   // 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;
 
-  // not globally unqiue, but each parent ensures that
-  // its children have unique identifiers, including to
-  // the parent itself
-  int instanceID;
+  // a parent waits on this semaphore when stalling on
+  // this child, the child gives it at its SESE exit
+  psemaphore stallSem;
 
-  // for state of vars after issue
-  struct SESEvar* vars;
   
-  // when this sese is ready to be invoked,
-  // allocate and fill in this structure, and
-  // the primitives will be passed out of the
-  // above var array at the call site
-  void* paramStruct;
-};
-
-
-void mlpInit();
-
-void mlpIssue     ( struct SESErecord* sese );
-void mlpStall     ( struct SESErecord* sese );
-void mlpNotifyExit( struct SESErecord* sese );
+  // 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 BinItem_t* binitem;
+  struct Vector_t* vector;
+  struct SCC_t* scc;
+  struct MemoryQueue_t* queue;
+  psemaphore parentStallSem;
+  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; 
+} MemoryQueueItem;
+
+typedef struct MemoryQueue_t {
+  MemoryQueueItem * head;
+  MemoryQueueItem * tail;  
+  REntry * binbuf[NUMBINS];
+  REntry * buf[NUMRENTRY];
+  int bufcount;
+} MemoryQueue;
+
+typedef struct BinItem_t {
+  int total;
+  int status;       //NOTREADY, READY
+  int type;         //READBIN:0, WRITEBIN:1
+  struct BinItem_t * next;
+} BinItem;
+
+typedef struct Hashtable_t {
+  MemoryQueueItem item;
+  struct BinElement_t* array[NUMBINS];
+  struct Queue*   unresolvedQueue;
+} Hashtable;
+
+typedef struct BinElement_t {
+  BinItem * head;
+  BinItem * tail;
+} BinElement;
+
+typedef struct WriteBinItem_t {
+  BinItem item;
+  REntry * val;
+} WriteBinItem;
+
+typedef struct ReadBinItem_t {
+  BinItem item;
+  REntry * array[NUMREAD];
+  int index;
+} ReadBinItem;
+
+typedef struct Vector_t {
+  MemoryQueueItem item;
+  REntry * array[NUMITEMS];
+  int index;
+} Vector;
+
+typedef struct SCC_t {
+  MemoryQueueItem item;
+  REntry * val;
+} SCC;
+
+int ADDRENTRY(MemoryQueue* q, REntry * r);
+void RETIRERENTRY(MemoryQueue* Q, REntry * r);
+
+
+
+// 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);
+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__ */