Very, very rough draft of the hash structure to be used in the upcomming version...
authorstephey <stephey>
Wed, 1 Sep 2010 02:31:06 +0000 (02:31 +0000)
committerstephey <stephey>
Wed, 1 Sep 2010 02:31:06 +0000 (02:31 +0000)
Robust/src/Runtime/oooJava/hashStructure.c [new file with mode: 0644]

diff --git a/Robust/src/Runtime/oooJava/hashStructure.c b/Robust/src/Runtime/oooJava/hashStructure.c
new file mode 100644 (file)
index 0000000..16002eb
--- /dev/null
@@ -0,0 +1,233 @@
+#include "hashStructure.h"
+#include "tm.h"
+
+//TODO since hashtables can be shared amongst traversers and there's a finite number,
+//have a structure to keep track of all the hash tables for HRs.
+
+Hashtable* createHashtable(){
+  int i=0;
+  Hashtable* newTable=(Hashtable*)RUNMALLOC(sizeof(Hashtable));
+  for(i=0;i<NUMBINS;i++){
+    newTable->array[i]=(BinElement*)RUNMALLOC(sizeof(BinElement));
+    newTable->array[i]->head=NULL;
+    newTable->array[i]->tail=NULL;
+  }
+
+  //Todo edit here to make this be pointed to a generated waitingQueue
+  newTable->unresolvedQueue=NULL;
+  return newTable;
+}
+
+
+WriteBinItem* createWriteBinItem(){
+  WriteBinItem* binitem=(WriteBinItem*)RUNMALLOC(sizeof(WriteBinItem));
+  binitem->item.type=WRITEBIN;
+  return binitem;
+}
+
+ReadBinItem* createReadBinItem(){
+  ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem));
+  binitem->index=0;
+  binitem->item.type=READBIN;
+  return binitem;
+}
+
+int isReadBinItem(BinItem* b){
+  if(b->type==READBIN){
+    return TRUE;
+  }else{
+    return FALSE;
+  }
+}
+
+int isWriteBinItem(BinItem* b){
+  if(b->type==WRITEBIN){
+    return TRUE;
+  }else{
+    return FALSE;
+  }
+}
+
+inline int generateKey(void * ptr){
+  return ((struct genericObjectStruct *) ptr)->oid&H_MASK;
+}
+
+//TODO handle logic for waiting Queues separately
+//TODO pass in task to traverser
+int ADDTABLEITEM(Hashtable* table, void * ptr, int type, int traverserID, SESEcommon *task, void * heaproot){
+  BinItem * val;
+  int key=generateKey(ptr);
+  do {
+    val=(BinItem*)0x1;
+    BinElement* bin=table->array[key];
+    val=(BinItem*)LOCKXCHG((unsigned INTPTR*) (&(bin->head)), (unsigned INTPTR)val);
+  } while(val==(BinItem*)0x1);
+  //at this point have locked bin
+  if (val==NULL) {
+    return EMPTYBINCASE(table, table->array[key], ptr, type, traverserID, task, heaproot);
+  } else {
+    //else create item
+    if (type == WRITEEFFECT) {
+      return WRITEBINCASE(table, ptr, val, key, traverserID, task, heaproot);
+    } else if (type == READEFFECT) {
+      return READBINCASE(table, ptr, val, key, traverserID, task, heaproot);
+    }
+  }
+}
+
+int EMPTYBINCASE(Hashtable *T, BinElement* be, void *ptr, int type, int traverserId, SESEcommon * task, void *heaproot) {
+  BinItem* b;
+  TraverserData * td;
+  if (type == WRITEEFFECT) {
+    b=(BinItem*)createWriteBinItem();
+    td = &((WriteBinItem*)b)->val;
+  }
+  else if (type == READEFFECT) {
+    b=(BinItem*)createReadBinItem();
+    ReadBinItem* readbin=(ReadBinItem*)b;
+    td = &(readbin->array[readbin->index++]);
+  }
+  b->total=1;
+  b->type= type;
+  b->status = READY;
+
+  //common to both types
+  td->binitem = b;
+  td->hashtable=T;
+  td->pointer = ptr;
+  td->task= task;
+  td->traverserID = traverserId;
+  td->heaproot = heaproot;
+
+  be->tail=b;
+  be->head=b;//released lock
+
+  return READY;
+}
+
+
+int WRITEBINCASE(Hashtable *T, void *ptr, BinItem *originalHead, int key, int traverserID, SESEcommon *task, void *heaproot) {
+  //chain of bins exists => tail is valid
+  //if there is something in front of us, then we are not ready
+  int status=NOTREADY;
+  BinElement* be=T->array[key]; //do not grab head from here since it's locked (i.e. = 0x1)
+
+  if(be->tail->type == WRITEBIN) {
+    TraverserData * td = &(((WriteBinItem *)be->tail)->val);
+    if(unlikely(td->pointer == ptr) && td->traverserID == traverserID) {
+      be->head = originalHead; //lock released
+      return be->tail->status;
+    }
+  } else if(be->tail->type == READBIN) {
+    TraverserData * td = &((ReadBinItem *)be->tail)->array[((ReadBinItem *)be->tail)->index - 1];
+    if(unlikely(td->pointer == ptr) && td->traverserID == traverserID) {
+      //if it matches, then we remove it and the code below will upgrade it to a write.
+      ((ReadBinItem *)be->tail)->index--;
+      be->tail->total--;
+    }
+  }
+
+  WriteBinItem *b=createWriteBinItem();
+  TraverserData * td = &b->val;
+  b->item.total=1;
+
+  //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 = b;
+  td->hashtable=T;
+  td->pointer = ptr;
+  td->task= task;
+  td->traverserID = traverserID;
+  td->heaproot = heaproot;
+
+  b->item.status=status;
+  be->tail->next=(BinItem*)b;
+  be->tail=(BinItem*)b;
+  be->head=originalHead; // lock released
+  return status;
+}
+
+int READBINCASE(Hashtable *T, void *ptr, BinItem *originalHead, int key, int traverserID, SESEcommon * task, void *heaproot) {
+  BinElement * be = T->array[key];
+  BinItem * bintail=be->tail;
+  //check if already added item or not.
+  if(bintail->type == WRITEBIN) {
+    TraverserData * td = &(((WriteBinItem *)bintail)->val);
+    if(unlikely(td->pointer == ptr) && td->traverserID == traverserID) {
+      be->head = originalHead; //lock released
+      return bintail->status;
+    }
+  }
+  else if(bintail->type == READEFFECT) {
+    TraverserData * td = &((ReadBinItem *)bintail)->array[((ReadBinItem *)bintail)->index - 1];
+    if(unlikely(td->pointer == ptr) && td->traverserID == traverserID) {
+      return bintail->status;
+  }
+
+  if (isReadBinItem(bintail)) {
+    return TAILREADCASE(T, ptr, originalHead, bintail, key, traverserID, task, heaproot);
+  } else if (!isReadBinItem(bintail)) {
+    TAILWRITECASE(T, ptr, originalHead, bintail, key, traverserID, task, heaproot);
+    return NOTREADY;
+  }
+}
+
+int TAILREADCASE(Hashtable *T, void * ptr, BinItem *originalHead, BinItem *bintail, int key, int traverserID, SESEcommon * task, void *heaproot) {
+  ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail;
+  int status, retval;
+  TraverserData *td;
+  if (readbintail->item.status==READY) {
+    status=READY;
+    retval=READY;
+  } else {
+    status=NOTREADY;
+    retval=NOTREADY;
+  }
+
+  if (readbintail->index==NUMREAD) { // create new read group
+    ReadBinItem* rb=createReadBinItem();
+    td = &rb->array[rb->index++];
+
+    rb->item.total=1;
+    rb->item.status=status;
+    T->array[key]->tail->next=(BinItem*)rb;
+    T->array[key]->tail=(BinItem*)rb;
+  } 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->pointer = ptr;
+  td->task= task;
+  td->traverserID = traverserID;
+  td->heaproot = heaproot;
+
+  T->array[key]->head=originalHead;//released lock
+  return retval;
+}
+
+void TAILWRITECASE(Hashtable *T, void *ptr, BinItem *val, BinItem *bintail, int key, int traverserID, SESEcommon * task, void *heaproot) {
+  //  WriteBinItem* wb=createWriteBinItem();
+  //wb->val=r;
+  //wb->item.total=1;//safe because item could not have started
+  //wb->item.status=NOTREADY;
+  ReadBinItem* rb=createReadBinItem();
+  TraverserData * td = &(rb->array[rb->index++]);
+  rb->item.total=1;//safe because item could not have started
+  rb->item.status=NOTREADY;
+
+  td->binitem = rb;
+  td->hashtable=T;
+  td->pointer = ptr;
+  td->task= task;
+  td->traverserID = traverserID;
+  td->heaproot = heaproot;
+
+  T->array[key]->tail->next=(BinItem*)rb;
+  T->array[key]->tail=(BinItem*)rb;
+  T->array[key]->head=val;//released lock
+}
+