changes
authorbdemsky <bdemsky>
Tue, 19 Oct 2010 21:33:43 +0000 (21:33 +0000)
committerbdemsky <bdemsky>
Tue, 19 Oct 2010 21:33:43 +0000 (21:33 +0000)
Robust/src/Runtime/oooJava/hashStructure.c
Robust/src/Runtime/oooJava/hashStructure.h

index 872263b2fee6bcb7a8c6547434f0ddd410f0dc4d..3d1e03036e0d6d0e3d88071d25b717fa5bb8f249 100644 (file)
@@ -6,6 +6,10 @@
 //NOTE: this is only temporary (for testing) and will be removed in favor of thread local variables
 //It's basically an array of hashStructures so we can simulate what would happen in a many-threaded version
 HashStructure ** allHashStructures;
+#define ISWRITEBIN(x) (x&BINMASK)
+#define ISREADBIN(x) (!(x&BINMASK))
+//#define POPCOUNT(x) __builtin_popcountll(x)
+//__builtin_popcountll
 
 //NOTE: only temporary
 void rcr_createMasterHashTableArray(int maxSize){
@@ -19,7 +23,6 @@ HashStructure* rcr_createHashtable(int sizeofWaitingQueue){
     newTable->array[i].tail=NULL;
   }
 
-  //  newTable->waitingQueue=mallocWaitingQueue(sizeofWaitingQueue);
   return newTable;
 }
 
@@ -36,19 +39,11 @@ ReadBinItem_rcr* rcr_createReadBinItem(){
   return binitem;
 }
 
-int rcr_isReadBinItem(BinItem_rcr* b){
-  return b->type==READBIN;
-}
-
-int rcr_isWriteBinItem(BinItem_rcr* b){
-  return b->type==WRITEBIN;
-}
-
 inline int rcr_generateKey(void * ptr){
-  return (((struct genericObjectStruct *) ptr)->oid)&RH_MASK;
+  return (((struct ___Object___ *) ptr)->oid)&RH_MASK;
 }
 
-int rcr_WRITEBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon *task, void *heaproot) {
+int rcr_WRITEBINCASE(HashStructure *T, void *ptr, SESEcommon *task, int index) {
   //chain of bins exists => tail is valid
   //if there is something in front of us, then we are not ready
   BinItem_rcr * val;
@@ -68,12 +63,8 @@ int rcr_WRITEBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon *t
     b->status=READY;
     
     //common to both types
-    td->binitem = b;
-    td->hashtable=T;
-    td->resumePtr = ptr;
-    td->task= task;
-    td->traverserID = traverserID;
-    td->heaproot = heaproot;
+    td->task=task;
+    td->bitindex=1<<index;
     be->tail=b;
     
     //release lock
@@ -81,48 +72,69 @@ int rcr_WRITEBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon *t
     return READY;
   }
 
-  int status=NOTREADY;
   BinItem_rcr *bintail=be->tail;
+  bitv rdmask=0,wrmask=0;
+  int status=NOTREADY;
 
-  if (bintail->type == WRITEBIN) {
-    TraverserData * td = &(((WriteBinItem_rcr *)bintail)->val);
+  if (ISWRITEBIN(bintail->type)) {
+    WriteBinItem_rcr * td = (WriteBinItem_rcr *)bintail;
     //last one is to check for SESE blocks in a while loop.
     if(unlikely(td->task == task)) {
       be->head=val;
-      //return ready...this constraint is already handled
-      return READY;
+      bitv bit=1<<index;
+      if (!(bit & td->bitindexwr)) {
+       td->bitindexwr|=bit;
+       td->bitindexrd|=bit;
+       return (bintail->status==READY)?READY:SPECNOTREADY;
+      } else
+       return READY;
     }
-  } else if (bintail->type == READBIN) {
+  } else {
     TraverserData * td = &((ReadBinItem_rcr *)bintail)->array[((ReadBinItem_rcr *)bintail)->index - 1];
     if(unlikely(td->task == task)) {
       //if it matches, then we remove it and the code below will upgrade it to a write.
       ((ReadBinItem_rcr *)bintail)->index--;
-      bintail->total--;
+      atomic_dec(&bintail->total);
+      rdmask=tr->bitindex;
+      if (bintail->status!=READY)
+       wrmask=rdmask;
+      status=SPECNOTREADY;
     }
   }
 
   WriteBinItem_rcr *b=rcr_createWriteBinItem();
-  TraverserData * td = &b->val;
   b->item.total=1;
+  b->task=task;
 
-  //fillout traverserData
-  //Note: this list could be smaller in the future, for now I'm just including all the info I may need.
-  td->binitem = (BinItem_rcr*)b;
-  td->hashtable=T;
-  td->resumePtr = ptr;
-  td->task= task;
-  td->traverserID = traverserID;
-  td->heaproot = heaproot;
-
+  bitv bit=1<<index;
+  if (wrmask&bit) {
+    //count already includes this
+    status=READY;
+  }
+  b->bitindexwr=bit|wrmask;
+  b->bitindexrd=bit|rdmask;
   b->item.status=status;
   bintail->next=(BinItem_rcr*)b;
   be->tail=(BinItem_rcr*)b;
+  
+  if (bintail->status==READY&&bintail->total==0) {
+    //we may have to set write as ready
+    while(val->total==0) {
+      if (val==b) {
+       b->item.status=READY;
+       be->head=val;
+       return READY;
+      }
+      val=val->next;
+    }
+  }
+
   //RELEASE LOCK
   be->head=val;
   return status;
 }
 
-int rcr_READBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon * task, void *heaproot) {
+int rcr_READBINCASE(HashStructure *T, void *ptr, SESEcommon * task, int index) {
   BinItem_rcr * val;
   int key=rcr_generateKey(ptr);
   BinElement_rcr * be = &(T->array[key]);
@@ -138,15 +150,11 @@ int rcr_READBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon * t
     ReadBinItem_rcr* readbin=(ReadBinItem_rcr*)b;
     TraverserData * td = &(readbin->array[readbin->index++]);
     b->total=1;
-    b->status = READY;
+    b->status=READY;
     
     //common to both types
-    td->binitem = b;
-    td->hashtable=T;
-    td->resumePtr = ptr;
-    td->task= task;
-    td->traverserID = traverserID;
-    td->heaproot = heaproot;
+    td->task=task;
+    td->bitindex=1<<index;
     be->tail=b;
     
     //release lock
@@ -159,32 +167,49 @@ int rcr_READBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon * t
   BinItem_rcr * bintail=be->tail;
 
   //check if already added item or not.
-  if (bintail->type == WRITEBIN) {
-    TraverserData * td = &(((WriteBinItem_rcr *)bintail)->val);
-    if(unlikely(td->resumePtr == ptr) && td->traverserID == traverserID) {
+  if (ISWRITEBIN(bintail->type)) {
+    WriteBinItem_rcr td = (WriteBinItem_rcr *)bintail;
+    if(unlikely(td->task==task)) {
       //RELEASE LOCK
+      bitv bit=1<<index;
+      int status=bintail->status;
+      if (!(td->bitindexrd & bit)) {
+       td->bitindexrd|=bit;
+       td->bitindexwr|=bit;
+       if (status==NOTREADY)
+         status=SNOTREADY;
+      } else 
+       status=READY;
       be->head=val;
-      return bintail->status;
+      return status;
     }
-  } else if (bintail->type == READEFFECT) {
+  } else {
     TraverserData * td = &((ReadBinItem_rcr *)bintail)->array[((ReadBinItem_rcr *)bintail)->index - 1];
-    if (unlikely(td->resumePtr == ptr) && td->traverserID == traverserID) {
+    if (unlikely(td->task==task)) {
       //RELEASE LOCK
+      bitv bit=1<<index;
+      int status=bintail->status;
+      if (!(td->bitindex & bit)) {
+       td->bitindex|=bit;
+       if (status==NOTREADY)
+         status=SNOTREADY;
+      } else 
+       status=READY;
       be->head=val;
-      return bintail->status;
+      return status;
     }
   }
 
-  if (isReadBinItem(bintail)) {
-    return rcr_TAILREADCASE(T, ptr, val, bintail, key, traverserID, task, heaproot);
-  } else if (!isReadBinItem(bintail)) {
-    rcr_TAILWRITECASE(T, ptr, val, bintail, key, traverserID, task, heaproot);
+  if (ISREADBIN(bintail->type)) {
+    return rcr_TAILREADCASE(T, ptr, val, bintail, key, task, index);
+  } else {
+    rcr_TAILWRITECASE(T, ptr, val, bintail, key, task, index);
     return NOTREADY;
   }
 }
 
 
-int rcr_TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot) {
+int rcr_TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index) {
   ReadBinItem_rcr * readbintail=(ReadBinItem_rcr*)T->array[key].tail;
   int status, retval;
   TraverserData *td;
@@ -207,172 +232,92 @@ int rcr_TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *val, BinItem_rcr
   } else { // group into old tail
     td = &readbintail->array[readbintail->index++];
     atomic_inc(&readbintail->item.total);
-    //printf("grouping with %d\n",readbintail->index);
   }
 
-  td->binitem = bintail;
-  td->hashtable=T;
-  td->resumePtr = ptr;
-  td->task= task;
-  td->traverserID = traverserID;
-  td->heaproot = heaproot;
+  td->task=task;
+  td->bitindex=1<<index;
 
   T->array[key].head=val;//released lock
   return retval;
 }
 
-void rcr_TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot) {
+void rcr_TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index) {
   ReadBinItem_rcr* rb=rcr_createReadBinItem();
   TraverserData * td = &(rb->array[rb->index++]);
   rb->item.total=1;
   rb->item.status=NOTREADY;
 
   td->binitem = (BinItem_rcr *) rb;
-  td->hashtable=T;
-  td->resumePtr = ptr;
-  td->task= task;
-  td->traverserID = traverserID;
-  td->heaproot = heaproot;
+  td->task=task;
+  td->bitindex=1<<index;
 
   T->array[key].tail->next=(BinItem_rcr*)rb;
   T->array[key].tail=(BinItem_rcr*)rb;
   T->array[key].head=val;//released lock
 }
 
-//TODO write deletion/removal methods
-
 RETIREHASHTABLE(HashStructure *T, SESECommon *task, int key) {
-  BinItem_rcr *b=T->array[key].head;
-  if(isFineRead(r)) {
+  BinElement_rcr * be = &(T->array[key]);  
+  BinItem_rcr *b=be->head;
+
+  if(ISREADBIN(READBIN)) {
     atomic_dec(&b->total);
+    if (b->next==NULL || b->total>0) {
+      return;
+    }
   }
-  if (isFineWrite(r) || (isFineRead(r) && b->next!=NULL && b->total==0)) {
+  //We either have a write bin or we are at the end of a read bin
+
+  {
     // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change
-    BinItem_rcr * val;
-    do {  
-      val=(BinItem_rcr*)0x1;
-      val=(BinItem_rcr*)LOCKXCHG((unsigned INTPTR*)&(T->array[key]->head), (unsigned INTPTR)val);
+    BinItem_rcr * val=(BinItem_rcr *)0x1;
+    do {
+      val=(BinItem_rcr*)LOCKXCHG((unsigned INTPTR*)&(be->head), (unsigned INTPTR)val);
     } while(val==(BinItem_rcr*)0x1);
-
+    
     // at this point have locked bin
     BinItem_rcr *ptr=val;
     int haveread=FALSE;
     int i;
     while (ptr!=NULL) {
-       if (isReadBinItem(ptr)) {
-       ReadBinItem_rcr* rptr=(ReadBinItem_rcr*)ptr;
-        if (rptr->item.status==NOTREADY) {
-          for (i=0;i<rptr->index;i++) {            
-           resolveDependencies(rptr->array[i]);
-            if (isParent(rptr->array[i])) {
+      if (ISREADBIN(ptr->type)) {
+       if (ptr->status==NOTREADY) {
+         ReadBinItem_rcr* rptr=(ReadBinItem_rcr*)ptr;
+         for (i=0;i<rptr->index;i++) {
+           RESOLVE(rptr->array[i]);
+            if (((INTPTR)rptr->array[i]->task)&PARENTBIN) {
               //parents go immediately
               atomic_dec(&rptr->item.total);
-              atomic_dec(&T->item.total);
             }
           }
+         ptr->status=READY;
         }
-        rptr->item.status=READY; 
-        if (rptr->item.next==NULL) {
+        if (ptr->next==NULL) {
           break;
         }
-        if (rptr->item.total!=0) {
-          haveread=TRUE; 
-        } else if ((BinItem_rcr*)rptr==val) {
+        if (ptr->total!=0) {
+          haveread=TRUE;
+        } else if (ptr==val) {
           val=val->next;
         }
-      } else if(isWriteBinItem(ptr)) {
-        if (haveread)  
+      } else {
+       //write bin case
+        if (haveread)
           break;
-       if(ptr->status==NOTREADY){
-         resolveDependencies(((WriteBinItem_rcr*)ptr)->val);
+       if(ptr->status==NOTREADY) {
+         WriteBinItem_rcr* wptr=(WriteBinItem_rcr*)ptr;
+         RESOLVE(wptr->val);
          ptr->status=READY;
-         if(isParent(((WriteBinItem_rcr*)ptr)->val)){
-           atomic_dec(&T->item.total);
-           val=val->next;        
-         }else
+         if(((INTPTR)wptr->task)&PARENTBIN) {
+           val=val->next;
+         } else
            break;
-       }else{ // write bin is already resolved
+       } else { // write bin is already resolved
          val=val->next;
        }
-      } 
-      ptr=ptr->next;
-    }
-    T->array[key]->head=val; // release lock
-  }
-}
-
-
-/*
-//Int will return success/fail. -1 indicates error (i.e. there's nothing there).
-//0 = nothing removed, >0 something was removed
-int REMOVETABLEITEM(HashStructure* table, void * ptr, int traverserID, SESEcommon *task, void * heaproot) {
-  int key = generateKey(ptr);
-  BinElement_rcr * bucket = table->array[key];
-
-  if(bucket->head == NULL) {
-    return -1;
-    //This can occur if we try to remove something that's in the waitingQueue directly from the hashtable.
-  }
-
-  if(bucket->head->type == WRITEBIN) {
-    TraverserData * td = &(((WriteBinItem_rcr *) head)->val);
-    if(td->resumePtr == ptr && td->traverserID == traverserID && td->heaproot == heaproot) {
-      BinItem_rcr * temp = bucket->head;
-      bucket->head = bucket->head->next;
-      free(temp); //TODO perhaps implement a linked list of free BinElements as was done in WaitingQueue
-
-      //Handle items behind write item
-      if(bucket->head == NULL) {
-        bucket->tail == NULL;
-        return 1;
-      }
-
-      int type = bucket->head->type;
-      switch(bucket->head->type) {
-        case WRITEBIN:
-          bucket->head->status = READY;
-          //TODO Decrement dependency count
-          return 1;
-        case WAITINGQUEUENOTE:
-          int retval = removeFromWaitingQueue(table->waitingQueue, ((WaitingQueueNote *) bucket->head)->allocSiteID, traverserID);
-          if(retval >0) {
-            //we set both to NULL because the note should ALWAYS be the last item in the hashStructure.
-             bucket->head = NULL;
-             bucket->tail = NULL;
-          }
-          return retval;
-        default:
-          BinItem_rcr * temp = bucket->head;
-          while(temp != NULL && temp->type == READBIN) {
-            temp->status = READY;
-            temp = temp->next;
-            //TODO decrement dependency count
-          }
-          return 1;
       }
-    } else {
-      return 0;
-    }
-  }
-
-  if(bucket->head->type == READBIN) {
-    //TODO There's an issue here; bins are groups of items that may be enqueued by different ids.
-    //I may have to search through them to find which one to remove but then there'd be a blank spot in an
-    //otherwise clean array. It wouldn't make sense to just check the first one since reads are reorderable.
-    //Nor does it make sense to lop off the reads since that may signal the next write to be ready even before it
-    //really is ready.
-  }
-
-  if(bucket->head->type == WAITINGQUEUENOTE) {
-    int retval = removeFromWaitingQueue(table->waitingQueue, ((WaitingQueueNote *) bucket->head)->allocSiteID, traverserID);
-    if(retval >0) {
-       bucket->head = NULL;
-       bucket->tail = NULL;
+      ptr=ptr->next;
     }
-    return retval;
+    be->head=val; // release lock
   }
-
-  return -1;
 }
-
-*/
index 1bcde9e7d33edbdf1ebf1985781cee92f0fe21b6..a645502bd5886aaa02cfd61eca12876f6b9fdd34 100644 (file)
@@ -6,7 +6,7 @@
 \r
 #define ITEM_NOT_AT_FRONT_OF_WAITINGQ 3\r
 #define TRAVERSER_FINISHED 2\r
-\r
+#define bitvt unsigned long long\r
 \r
 //Note READEFFECT = READBIN and WRITEEFFECT=WRITEBIN. They mean the same thing\r
 //but are named differently for clarity in code.\r
 \r
 #define READBIN 0\r
 #define WRITEBIN 1\r
+#define BINMASK 1\r
+#define PARENTBIN 1\r
 \r
+#define SPECNOTREADY 2\r
 #define READY 1\r
 #define NOTREADY 0\r
 \r
@@ -37,54 +40,27 @@ typedef struct BinItem_rcr {
   struct BinItem_rcr * next;\r
 } BinItem_rcr;\r
 \r
-typedef struct trackerElement {\r
-  BinItem_rcr * item;\r
-  struct trackerElement * next;\r
-} TrackerElement;\r
-\r
-typedef struct tracker {\r
-  TrackerElement * head;\r
-  TrackerElement * tail;\r
-} VariableTracker;\r
-\r
-//TODO more closely tie this in with Jim's stuff\r
-struct genericObjectStruct {\r
-        int type;\r
-        int oid;\r
-        int allocsite;\r
-        int ___cachedCode___;\r
-        int ___cachedHash___;\r
-};\r
-\r
-\r
 typedef struct BinElement_rcr {\r
   BinItem_rcr * head;\r
   BinItem_rcr * tail;\r
 } BinElement_rcr;\r
 \r
-\r
 typedef struct Hashtable_rcr {\r
   BinElement_rcr array[RNUMBINS];\r
   //  WaitingQueueBin * waitingQueue;\r
 } HashStructure;\r
 \r
 //Todo this is a clone of REntry, remove data fields as necessary\r
-typedef struct entry_rcr{\r
-  //fields to handle next item.\r
-  struct Hashtable_rcr* hashtable;\r
-  BinItem_rcr* binitem; //stores binItem so we can get access to the next ptr in the queue\r
-\r
-  //fields to help resume traverser\r
-  struct genericObjectStruct * resumePtr;\r
-//  int allocsite; //not needed since we can get it form ptr later\r
-  int traverserID;\r
+typedef struct Entry_rcr {\r
   SESEcommon * task;\r
-  struct genericObjectStruct * heaproot;\r
+  bitv bitindex;\r
 } TraverserData;\r
 \r
 typedef struct WriteBinItem_rcr {\r
   BinItem_rcr item;\r
-  TraverserData val;\r
+  SESEcommon * task;\r
+  bitv bitindexwr;\r
+  bitv bitindexrd;\r
 } WriteBinItem_rcr;\r
 \r
 typedef struct ReadBinItem_rcr {\r
@@ -92,14 +68,8 @@ typedef struct ReadBinItem_rcr {
   TraverserData array[RNUMREAD];\r
   //We don't need a head index since if the item before it was freed, then all these would be considered ready as well.\r
   int index;\r
-  \r
 } ReadBinItem_rcr;\r
 \r
-typedef struct WQNote_rcr {\r
-  BinItem_rcr item;\r
-  int allocSiteID;\r
-} WaitingQueueNote;\r
-\r
 extern HashStructure ** allHashStructures;\r
 \r
 void rcr_createMasterHashTableArray(int maxSize); //temporary\r
@@ -113,10 +83,9 @@ inline int rcr_generateKey(void * ptr);
 //Method signatures are not in their final form since I have still not decided what is the optimum amount of data\r
 //to store in each entry.\r
 \r
-int rcr_WRITEBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon *task, void *heaproot);\r
-int rcr_READBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon * task, void *heaproot);\r
-int rcr_TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot);\r
-void rcr_TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot);\r
-int rcr_REMOVETABLEITEM(HashStructure* table, void * ptr, int traverserID, SESEcommon *task, void * heaproot);\r
+int rcr_WRITEBINCASE(HashStructure *T, void *ptr, SESEcommon *task, void *heaproot);\r
+int rcr_READBINCASE(HashStructure *T, void *ptr, SESEcommon * task, void *heaproot);\r
+int rcr_TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, void *heaproot);\r
+void rcr_TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, void *heaproot);\r
 \r
 #endif\r