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 75753ad1e922e91cc7bed46dfc9950f2cec848e1..4e351a50974a73fac14bffc48908328d3cf24d58 100644 (file)
 
 #include <pthread.h>
 #include "Queue.h"
+#include "psemaphore.h"
+#include "mlp_lock.h"
+#include "memPool.h"
 
+#ifndef FALSE
+#define FALSE 0
+#endif
 
-// a forward delcaration for SESEvar
-struct SESErecord_t;
+#ifndef TRUE
+#define TRUE 1
+#endif
 
+#define NUMBINS 64
+#define NUMREAD 64
+#define NUMITEMS 64
+#define NUMRENTRY 256
 
-typedef struct SESEvar_t {
-  //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;
-    int       sesetype_boolean;
-    short     sesetype_short;
-    int       sesetype_int;
-    long long sesetype_long;
-    short     sesetype_char;
-    float     sesetype_float;
-    double    sesetype_double;
-    void*     sesetype_object;
-  };
-  
-  // a statically or dynamically known SESE
-  // to gather the variable's value from
-  // if source==NULL it indicates the root
-  // SESE, which has no record, just normal
-  // temp names
-  //struct SESErecord_t* source;
-  //unsigned int         index;
-} SESEvar;
+#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
 
-typedef struct SESErecord_t {  
-  // the identifier for the class of sese's that
-  // are instances of one particular static code block
-  int classID;
+#define HASHTABLE 0
+#define VECTOR 1
+#define SINGLEITEM 2
 
-  // not globally unqiue, but each parent ensures that
-  // its children have unique identifiers, including to
-  // the parent itself
-  int instanceID;
+#define READBIN 0
+#define WRITEBIN 1
 
-  // used to give out IDs to children
-  int childInstanceIDs;
+#define H_MASK (NUMBINS<<4)-1
 
-  // pointers to SESEs directly above or below
-  // in the heirarchy
-  struct SESErecord_t* parent;
-  struct Queue*        childrenList;
+#ifndef FALSE
+#define FALSE 0
+#endif
 
-  // for state of vars after issue
-  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;
+#ifndef TRUE
+#define TRUE 1
+#endif
 
 
-  pthread_cond_t*  startCondVar;
-  pthread_mutex_t* startCondVarLock;
+#define OBJPTRPTR_2_OBJTYPE( opp ) ((int*)(*(opp)))[0]
+#define OBJPTRPTR_2_OBJOID(  opp ) ((int*)(*(opp)))[1]
 
 
-  // use a list of SESErecords and a lock to let
-  // consumers tell this SESE who wants values
-  // forwarded to it
-  pthread_mutex_t* forwardListLock;
-  struct Queue*    forwardList;
-  int doneExecuting;
-} SESErecord;
 
+// 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 {  
 
-typedef struct invokeSESEargs_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;
-  SESErecord* invokee;
-  SESErecord* parent;
-} invokeSESEargs;
 
+  // a parent waits on this semaphore when stalling on
+  // this child, the child gives it at its SESE exit
+  psemaphore stallSem;
 
-// simple mechanical allocation and deallocation
-// of SESE records
-SESErecord* mlpCreateSESErecord( int         classID,
-                                 int         instanceID,
-                                 SESErecord* parent,
-                                 int         numVars,
-                                 void*       paramStruct
-                                 );
-
-void mlpDestroySESErecord( SESErecord* sese );
-
-
-// main library functions
-void mlpInit();
-
-SESErecord* mlpGetCurrent();
-SESErecord* mlpSchedule();
-
-void mlpIssue     ( SESErecord* sese );
-void mlpStall     ( SESErecord* sese );
-void mlpNotifyExit( SESErecord* sese );
-
-
-extern SESErecord* rootsese;
+  
+  // 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__ */