changes: handle the case that there is only one work item after enqueue, then it...
authoryeom <yeom>
Wed, 6 Apr 2011 00:39:23 +0000 (00:39 +0000)
committeryeom <yeom>
Wed, 6 Apr 2011 00:39:23 +0000 (00:39 +0000)
Robust/src/Runtime/squeue.h

index f15c1a13f82b9077ba1b54865a42c2a675ca673a..73963c294d24f62b684722722a8cb3fc29ca42c0 100644 (file)
@@ -133,6 +133,35 @@ static inline void dqPushBottom( deque* p, void* work ) {
   p->tail=realptr;
 }
 
+static inline void* dqPopTopSelf(deque *p) {
+  int tryagain=1;
+  while(1) {
+  dequeItem *ptr=p->head;
+  dequeItem *realptr=(dequeItem *) EXTRACTPTR((INTPTR)ptr);
+  dequeItem *next=realptr->next;
+  //remove if we can..steal work no matter what
+  if (likely(next!=NULL)) {
+    if (((dequeItem *)CAS(&(p->head),(INTPTR)ptr, (INTPTR)next))!=ptr)
+      return DQ_POP_EMPTY;
+    void * item=NULL;
+    item=(void *)LOCKXCHG((unsigned INTPTR*) &(realptr->work), (unsigned INTPTR) item);
+    realptr->next=NULL;
+    BARRIER();
+    tagpoolfreeinto(&p->objret,ptr, realptr);
+    if (item==NULL&&tryagain) {
+      tryagain=0;
+      continue;
+    }
+    return item;
+  } else {
+    void * item=NULL;
+    if (realptr->work!=NULL)
+      item=(void *) LOCKXCHG((unsigned INTPTR*) &(realptr->work), (unsigned INTPTR) item);
+    return item;
+  }
+  }
+}
+
 static inline void* dqPopTop(deque *p) {
   dequeItem *ptr=p->head;
   dequeItem *realptr=(dequeItem *) EXTRACTPTR((INTPTR)ptr);
@@ -155,7 +184,7 @@ static inline void* dqPopTop(deque *p) {
   }
 }
 
-#define dqPopBottom dqPopTop
+#define dqPopBottom dqPopTopSelf
 
 #endif // ___MEMPOOL_H__