1 #include "mlp_lock.h"
\r
4 #include "WaitingQueue.h"
\r
5 #include "hashStructure.h"
\r
6 //TODO check that the right path is pointed to by the below #include
\r
7 #include "RuntimeConflictResolver.h"
\r
9 //Note: is global to all processes
\r
10 WaitingQueueBinVector * freeBinVectors;
\r
12 //TODO perhaps print a map of allocSites to arrayIndex?
\r
14 //NOTE: Only the HashTable calls this function
\r
15 WaitingQueueBin * mallocWaitingQueue(int size) {
\r
16 return (WaitingQueueBin *) malloc(sizeof(WaitingQueueBin) * size);
\r
19 //NOTE: allocSiteID is NOT the same as allocsite, rather it's an ID generated by the traverser for an alloc site for a traversal.
\r
20 void putIntoWaitingQueue(int allocSiteID, WaitingQueueBin * queue, void * resumePtr, int traverserID) {
\r
21 //since Put SHOULD be done only by 1 thread (from 1 hashtable), the locking mechanism is removed.
\r
22 WaitingQueueBin *qptr=&queue[allocSiteID];
\r
23 WaitingQueueBinVector * tail = qptr->tail;
\r
24 int effectType=0;//PLACEHOLDER....EITHER GET RID OF VARIABLE OR PASS IN
\r
27 //completely empty case
\r
28 WaitingQueueBinVector * currentVector = getUsableWaitingQueueBinVector();
\r
29 TraverserResumeDataFromWaitingQ * b = &(currentVector->array[currentVector->tailIndex++]);
\r
30 //Add new bin to list
\r
31 qptr->head = currentVector;
\r
32 qptr->tail = currentVector;
\r
33 //Insert item into bin
\r
34 b->resumePtr = resumePtr;
\r
35 b->traverserID = traverserID;
\r
36 b->effectType = effectType;
\r
38 } else if (tail->tailIndex == NUMITEMS_WQ) {
\r
40 WaitingQueueBinVector * currentVector = tail;
\r
41 TraverserResumeDataFromWaitingQ * b = &(currentVector->array[currentVector->tailIndex-1]);
\r
43 if(b->effectType != effectType || b->resumePtr != resumePtr || b->traverserID != traverserID) {
\r
45 currentVector = getUsableWaitingQueueBinVector();
\r
46 tail->next = currentVector;
\r
47 qptr->tail = currentVector;
\r
48 b = &(currentVector->array[currentVector->tailIndex++]);
\r
49 b->resumePtr = resumePtr;
\r
50 b->traverserID = traverserID;
\r
51 b->effectType = effectType;
\r
54 } else { //the bin not full case
\r
55 WaitingQueueBinVector * currentVector = tail;
\r
56 TraverserResumeDataFromWaitingQ * b = &(currentVector->array[currentVector->tailIndex-1]);
\r
58 if(b->effectType != effectType || b->resumePtr != resumePtr || b->traverserID != traverserID) {
\r
60 b = &(currentVector->array[currentVector->tailIndex++]);
\r
61 b->resumePtr = resumePtr;
\r
62 b->traverserID = traverserID;
\r
63 b->effectType = effectType;
\r
69 int isEmptyForWaitingQ(WaitingQueueBin * queue, int allocSiteID) {
\r
70 return queue[allocSiteID].size;
\r
73 //This method should be called by the SESE block
\r
74 //Return is how many things are removed. -1 would indicate error
\r
75 int removeFromWaitingQueue(WaitingQueueBin * wQueue, int allocSiteID, int TraverserID) {
\r
76 TraverserResumeDataFromWaitingQ * td;
\r
77 WaitingQueueBin * be = &(wQueue[allocSiteID]);
\r
80 if(wQueue[allocSiteID].size == 0)
\r
84 td = &(be->head->array[be->head->headIndex]);
\r
86 //TODO perhaps instead of using traverserID to track which variables are resolved, make
\r
87 //individual IDs for each.
\r
88 if(td->traverserID != TraverserID) {
\r
92 if(traverse(td->resumePtr, td->traverserID) == TRAVERSER_FINISHED) {
\r
93 count++; // means we at least got rid of 1 item in the traverser
\r
98 be->head->headIndex = 0;
\r
99 be->head->tailIndex = 0;
\r
102 else if(++(be->head->headIndex) == be->head->tailIndex){
\r
103 //Note: be->head->next CANNOT be NULL since that would imply be->size == 0
\r
104 be->head = returnWaitingQueueBinVectorToFreePool(be->head);
\r
113 WaitingQueueBinVector * returnWaitingQueueBinVectorToFreePool(WaitingQueueBinVector *ptr) {
\r
114 WaitingQueueBinVector * freeHead;
\r
115 WaitingQueueBinVector * ptrNext;
\r
117 freeHead = (WaitingQueueBinVector *) 0x1;
\r
118 freeHead = (WaitingQueueBinVector *) LOCKXCHG((unsigned INTPTR *)&freeBinVectors, (unsigned INTPTR) freeHead);
\r
119 } while (freeHead == (WaitingQueueBinVector *) 0x1);
\r
122 ptrNext = ptr->next;
\r
123 if(freeHead == NULL) {
\r
124 freeBinVectors = ptr; //lock released
\r
127 ptr->next = freeHead;
\r
128 freeBinVectors = ptr; //lock released
\r
134 WaitingQueueBinVector * getUsableWaitingQueueBinVector() {
\r
135 //Attempt to take one from the free bin first
\r
136 WaitingQueueBinVector * ptr;
\r
138 ptr = (WaitingQueueBinVector *) 0x1;
\r
139 ptr = (WaitingQueueBinVector *) LOCKXCHG((unsigned INTPTR *) &freeBinVectors, (unsigned INTPTR) ptr);
\r
140 } while (ptr == (WaitingQueueBinVector *) 0x1);
\r
144 freeBinVectors = NULL; //lock released
\r
145 return mallocNewWaitingQueueBinVector();
\r
147 freeBinVectors = ptr->next; //lock released
\r
149 ptr->headIndex = 0;
\r
150 ptr->tailIndex = 0;
\r
155 WaitingQueueBinVector * mallocNewWaitingQueueBinVector() {
\r
156 WaitingQueueBinVector * retval = (WaitingQueueBinVector *) malloc(
\r
157 sizeof(WaitingQueueBinVector));
\r
158 retval->next = NULL;
\r
159 retval->headIndex = 0;
\r
160 retval->tailIndex = 0;
\r