\r
//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
void putIntoWaitingQueue(int allocSiteID, WaitingQueueBin * queue, int effectType, void * resumePtr, int traverserID) {\r
- //lock bin\r
- WaitingQueueBinVector * currentVector;\r
- TraverserResumeDataFromWaitingQ * b;\r
-\r
-\r
//since Put SHOULD be done only by 1 thread (from 1 hashtable), the locking mechanism is removed.\r
- WaitingQueueBinVector * head = queue[allocSiteID].head;\r
-// do {\r
-// head = (WaitingQueueBinVector *) 0x1;\r
-// head = LOCKXCHG(&(queue[allocSiteID]).head, head);\r
-// } while (head == (WaitingQueueBinVector *) 0x1);\r
- //now the current bin is locked.\r
-\r
- //completely empty case\r
- if (queue[allocSiteID].tail == NULL) {\r
- currentVector = getUsableWaitingQueueBinVector();\r
- head = currentVector;\r
- queue[allocSiteID].tail = currentVector; //We do not set the head here because we need lock\r
- }\r
- //Tail bin full\r
- else if (queue[allocSiteID].tail->tailIndex == NUMITEMS_WQ) {\r
- currentVector = getUsableWaitingQueueBinVector();\r
- queue[allocSiteID].tail->next = currentVector;\r
- queue[allocSiteID].tail = currentVector;\r
- } else { //the bin not full case\r
- currentVector = queue[allocSiteID].tail;\r
- }\r
-\r
-\r
- //For the case in which we try to add the same thing twice\r
- b = &(currentVector->array[currentVector->tailIndex - 1]);\r
- if(b->effectType == effectType && b->resumePtr == resumePtr && b->traverserID == traverserID) {\r
- queue[allocSiteID].head = head; // release lock\r
- return;\r
- }\r
- else {//add item\r
- b = &(currentVector->array[currentVector->tailIndex++]);\r
-\r
+ WaitingQueueBin *qptr=&queue[allocSiteID];\r
+ WaitingQueueBinVector * tail = qptr->tail;\r
+\r
+ if (tail == NULL) {\r
+ //completely empty case\r
+ WaitingQueueBinVector * currentVector = getUsableWaitingQueueBinVector();\r
+ TraverserResumeDataFromWaitingQ * b = &(currentVector->array[currentVector->tailIndex++]);\r
+ //Add new bin to list\r
+ qptr->head = currentVector;\r
+ qptr->tail = currentVector;\r
+ //Insert item into bin\r
b->resumePtr = resumePtr;\r
b->traverserID = traverserID;\r
b->effectType = effectType;\r
-\r
- queue[allocSiteID].size++;\r
- queue[allocSiteID].head = head; // release lock\r
+ qptr->size++;\r
+ } else if (tail->tailIndex == NUMITEMS_WQ) {\r
+ //Tail bin full\r
+ WaitingQueueBinVector * currentVector = tail;\r
+ TraverserResumeDataFromWaitingQ * b = &(currentVector->array[currentVector->tailIndex-1]);\r
+ //Not a duplicate\r
+ if(b->effectType != effectType || b->resumePtr != resumePtr || b->traverserID != traverserID) {\r
+ //should add item\r
+ currentVector = getUsableWaitingQueueBinVector();\r
+ tail->next = currentVector;\r
+ qptr->tail = currentVector;\r
+ b = &(currentVector->array[currentVector->tailIndex++]);\r
+ b->resumePtr = resumePtr;\r
+ b->traverserID = traverserID;\r
+ b->effectType = effectType;\r
+ qptr->size++;\r
+ }\r
+ } else { //the bin not full case\r
+ WaitingQueueBinVector * currentVector = tail;\r
+ TraverserResumeDataFromWaitingQ * b = &(currentVector->array[currentVector->tailIndex-1]);\r
+ //Not a duplicate\r
+ if(b->effectType != effectType || b->resumePtr != resumePtr || b->traverserID != traverserID) {\r
+ //should add item\r
+ b = &(currentVector->array[currentVector->tailIndex++]);\r
+ b->resumePtr = resumePtr;\r
+ b->traverserID = traverserID;\r
+ b->effectType = effectType;\r
+ qptr->size++;\r
+ }\r
}\r
}\r
\r
-\r
int isEmptyForWaitingQ(WaitingQueueBin * queue, int allocSiteID) {\r
return (queue[allocSiteID]).size == 0;\r
}\r