HashStructure ** allHashStructures;
//NOTE: only temporary
-void createMasterHashTableArray(int maxSize) {
+void createMasterHashTableArray(int maxSize){
int i;
allHashTables = (HashTable**) malloc(sizeof(Hashtable) * maxSize);
ReadBinItem_rcr* createReadBinItem(){
ReadBinItem_rcr* binitem=(ReadBinItem_rcr*)RUNMALLOC(sizeof(ReadBinItem_rcr));
- binitem->index=0;
+ binitem->tail_Index=0;
+ binitem->head_Index=0;
binitem->item.type=READBIN;
return binitem;
}
}
}
-int EMPTYBINCASE(HashStructure *T, BinElement_rcr* be, void *ptr, int type, int traverserId, SESEcommon * task, void *heaproot) {
+int EMPTYBINCASE(HashStructure *T, BinElement_rcr* be, void *ptr, int type, int traverserId, SESEcommon * task, void *heaproot){
BinItem_rcr* b;
TraverserData * td;
if (type == WRITEEFFECT) {
else if (type == READEFFECT) {
b=(BinItem_rcr*)createReadBinItem();
ReadBinItem_rcr* readbin=(ReadBinItem_rcr*)b;
- td = &(readbin->array[readbin->index++]);
+ td = &(readbin->array[readbin->tail_Index++]);
}
b->total=1;
b->type= type;
}
-int WRITEBINCASE(HashStructure *T, void *ptr, int key, int traverserID, SESEcommon *task, void *heaproot) {
+int WRITEBINCASE(HashStructure *T, void *ptr, 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;
return be->tail->status;
}
} else if(be->tail->type == READBIN) {
- TraverserData * td = &((ReadBinItem_rcr *)be->tail)->array[((ReadBinItem_rcr *)be->tail)->index - 1];
+ TraverserData * td = &((ReadBinItem_rcr *)be->tail)->array[((ReadBinItem_rcr *)be->tail)->tail_Index - 1];
if(unlikely(td->resumePtr == ptr) && td->traverserID == traverserID) {
//if it matches, then we remove it and the code below will upgrade it to a write.
- ((ReadBinItem_rcr *)be->tail)->index--;
+ ((ReadBinItem_rcr *)be->tail)->tail_Index--;
be->tail->total--;
}
}
return status;
}
-int READBINCASE(HashStructure *T, void *ptr, int key, int traverserID, SESEcommon * task, void *heaproot) {
+int READBINCASE(HashStructure *T, void *ptr, int key, int traverserID, SESEcommon * task, void *heaproot){
BinElement_rcr * be = &(T->array[key]);
BinItem_rcr * bintail=be->tail;
//check if already added item or not.
}
}
else if(bintail->type == READEFFECT) {
- TraverserData * td = &((ReadBinItem_rcr *)bintail)->array[((ReadBinItem_rcr *)bintail)->index - 1];
+ TraverserData * td = &((ReadBinItem_rcr *)bintail)->array[((ReadBinItem_rcr *)bintail)->tail_Index - 1];
if(unlikely(td->resumePtr == ptr) && td->traverserID == traverserID) {
return bintail->status;
}
}
}
-int TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot) {
+int TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot){
ReadBinItem_rcr * readbintail=(ReadBinItem_rcr*)T->array[key].tail;
int status, retval;
TraverserData *td;
retval=NOTREADY;
}
- if (readbintail->index==NUMREAD) { // create new read group
+ if (readbintail->tail_Index==NUMREAD) { // create new read group
ReadBinItem_rcr* rb=createReadBinItem();
- td = &rb->array[rb->index++];
+ td = &rb->array[rb->tail_Index++];
rb->item.total=1;
rb->item.status=status;
T->array[key].tail->next=(BinItem_rcr*)rb;
T->array[key].tail=(BinItem_rcr*)rb;
} else { // group into old tail
- td = &readbintail->array[readbintail->index++];
+ td = &readbintail->array[readbintail->tail_Index++];
atomic_inc(&readbintail->item.total);
//printf("grouping with %d\n",readbintail->index);
}
return retval;
}
-void TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot) {
+void TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *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_rcr* rb=createReadBinItem();
- TraverserData * td = &(rb->array[rb->index++]);
+ TraverserData * td = &(rb->array[rb->tail_Index++]);
rb->item.total=1;
rb->item.status=NOTREADY;
T->array[key].tail=(BinItem_rcr*)rb;
}
-//TODO write deletion/removal methods
+//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;
+ }
+ return retval;
+ }
+
+ return -1;
+}
-#ifndef HASHSTRUCTURE_H_
-#define HASHSTRUCTURE_H_
-
-#include "mlp_runtime.h"
-#include "WaitingQueue.h"
-
-#define ITEM_NOT_AT_FRONT_OF_WAITINGQ = 3;
-#define TRAVERSER_FINISHED = 2;
-#define NUM_WAITING_Q_ITEMS 20
-
-#define READEFFECT 0
-#define WRITEEFFECT 1
-
-#define READBIN 0
-#define WRITEBIN 1
-
-#define READY 1
-#define NOTREADY 0
-
-#define TRUE 1
-#define FALSE 0
-
-#define NUMBINS 64
-#define NUMREAD 64
-#define NUMITEMS 64
-#define NUMRENTRY 256
-#define H_MASK (NUMBINS<<4)-1
-
-//Note: put resolved things at the end and unresolved at the front.
-typedef struct BinItem_rcr {
- int total;
- int status;
- int type;
- //TODO keep track of record ptr here
- struct BinItem_rcr * next;
-} BinItem_rcr;
-
-typedef struct trackerElement {
- BinItem_rcr * item;
- struct trackerElement * next;
-} TrackerElement;
-
-typedef struct tracker {
- TrackerElement * head;
- TrackerElement * tail;
-} VariableTracker;
-
-//TODO more closely tie this in with Jim's stuff
-struct genericObjectStruct {
- int type;
- int oid;
- int allocsite;
- int ___cachedCode___;
- int ___cachedHash___;
-};
-
-
-typedef struct BinElement_rcr {
- BinItem_rcr * head;
- BinItem_rcr * tail;
-} BinElement_rcr;
-
-
-typedef struct Hashtable_rcr {
- BinElement_rcr array[NUMBINS];
- WaitingQueueBin * waitingQueue;
-} HashStructure;
-
-//Todo this is a clone of REntry, remove data fields as necessary
-typedef struct entry_rcr{
- //fields to handle next item.
- struct Hashtable_rcr* hashtable;
- BinItem_rcr* binitem; //stores binItem so we can get access to the next ptr in the queue
-
- //fields to help resume traverser
- struct genericObjectStruct * resumePtr;
-// int allocsite; //not needed since we can get it form ptr later
- int traverserID;
- SESEcommon * task;
- struct genericObjectStruct * heaproot;
-} TraverserData;
-
-typedef struct WriteBinItem_rcr {
- BinItem_rcr item;
- TraverserData val;
-} WriteBinItem_rcr;
-
-typedef struct ReadBinItem_rcr {
- BinItem_rcr item;
- TraverserData array[NUMREAD];
- int index;
-} ReadBinItem_rcr;
-
-#endif
+#ifndef HASHSTRUCTURE_H_\r
+#define HASHSTRUCTURE_H_\r
+\r
+#include "mlp_runtime.h"\r
+#include "WaitingQueue.h"\r
+\r
+#define ITEM_NOT_AT_FRONT_OF_WAITINGQ = 3;\r
+#define TRAVERSER_FINISHED = 2;\r
+\r
+\r
+//Note READEFFECT = READBIN and WRITEEFFECT=WRITEBIN. They mean the same thing\r
+//but are named differently for clarity in code.\r
+#define READEFFECT 0\r
+#define WRITEEFFECT 1\r
+#define WAITINGQUEUENOTE 2;\r
+\r
+#define READBIN 0\r
+#define WRITEBIN 1\r
+\r
+#define READY 1\r
+#define NOTREADY 0\r
+\r
+#define TRUE 1\r
+#define FALSE 0\r
+\r
+#define NUMBINS 64\r
+#define NUMREAD 64\r
+#define NUMRENTRY 256\r
+#define H_MASK (NUMBINS<<4)-1\r
+\r
+//Note: put resolved things at the end and unresolved at the front.\r
+typedef struct BinItem_rcr {\r
+ int total;\r
+ int status;\r
+ int type;\r
+ //TODO keep track of record ptr here\r
+ 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[NUMBINS];\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
+ SESEcommon * task;\r
+ struct genericObjectStruct * heaproot;\r
+} TraverserData;\r
+\r
+typedef struct WriteBinItem_rcr {\r
+ BinItem_rcr item;\r
+ TraverserData val;\r
+} WriteBinItem_rcr;\r
+\r
+typedef struct ReadBinItem_rcr {\r
+ BinItem_rcr item;\r
+ TraverserData array[NUMREAD];\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 tail_Index;\r
+ int head_Index;\r
+} ReadBinItem_rcr;\r
+\r
+typedef struct WQNote_rcr {\r
+ BinItem_rcr item;\r
+ int allocSiteID;\r
+} WaitingQueueNote;\r
+\r
+void createMasterHashTableArray(int maxSize); //temporary\r
+HashStructure* createHashtable(int sizeofWaitingQueue);\r
+WriteBinItem_rcr* createWriteBinItem();\r
+ReadBinItem_rcr* createReadBinItem();\r
+int isReadBinItem(BinItem_rcr* b);\r
+int isWriteBinItem(BinItem_rcr* b);\r
+inline int generateKey(void * ptr);\r
+\r
+//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
+int ADDTABLEITEM(HashStructure* table, void * ptr, int type, int traverserID, SESEcommon *task, void * heaproot);\r
+int EMPTYBINCASE(HashStructure *T, BinElement_rcr* be, void *ptr, int type, int traverserId, SESEcommon * task, void *heaproot);\r
+int WRITEBINCASE(HashStructure *T, void *ptr, int key, int traverserID, SESEcommon *task, void *heaproot);\r
+int READBINCASE(HashStructure *T, void *ptr, int key, int traverserID, SESEcommon * task, void *heaproot);\r
+int TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot);\r
+void TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot);\r
+int REMOVETABLEITEM(HashStructure* table, void * ptr, int traverserID, SESEcommon *task, void * heaproot);\r
+\r
+#endif\r