示例#1
0
    data_type dequeue() {
        pointer_t tail, head, next;
        data_type val=NULL;
        while(true){ 
            head = this->head_; 
            tail = this->tail_; 
            next = (head.ptr)->next; 
            if (head != this->head_) continue;

            if(head.ptr == tail.ptr){
                if (next.ptr == NULL){ 
                    return 1;
                }
                pointer_t new_pt(next.ptr, tail.tag+1);
                CAS2(&(this->tail_), tail, new_pt);
            } else{ 
                val = next.ptr->value;
                pointer_t new_pt(next.ptr, head.tag+1);
                if(CAS2(&(this->head_), head, new_pt)){
                    break;
                }
            }
        }
        delete head.ptr;
        return val;
    }
示例#2
0
//----------------------------------------------------------------
fifocell *  fifoget(fifo * ff)
{
    fifocell * volatile head;
    fifocell * next;
    unsigned long ic, oc;
    short done = 0;

    do {
        oc = ff->oc;					/* read the head modification count */
        ic = ff->ic;					/* read the tail modification count */
        head = ff->head;				/* read the head cell */
        next = head->link;				/* read the next cell */
        if (oc == ff->oc) {				/* ensures that next is a valid pointer */
            /* to avoid failure when reading next value */
            if (head == ff->tail) {			/* is queue empty or tail falling behind? */
                if (next == fifo_end(ff))	/* is queue empty?             */
                    return 0;				/* queue is empty; return NULL */
                /* tail is pointing to head in a non empty queue, */
                /* try to set tail to the next cell               */
                CAS2 (&ff->tail, head, ic, next, ic+1);
            }
            else if (next != fifo_end(ff)) { /* if we are not competing on the dummy cell */
                /* and we try to set head to the next cell */
                done = CAS2 (&ff->head, head, oc, next, oc+1);
            }
        }
    } while (!done);
    msAtomicDec (&ff->count);
    if (head == &ff->dummy) {
        fifoput(ff,head);
        head = fifoget(ff);
    }
    return (fifocell *)head;
}
示例#3
0
//----------------------------------------------------------------
void fifoput (fifo * ff, fifocell * cl)
{
    long ic;
    fifocell * volatile tail;

    cl->link = fifo_end(ff);	/* set the cell next pointer to the end marker */
    while (1) {
        ic = ff->ic;			/* read the tail modification count */
        tail = ff->tail;		/* read the tail cell */
        /* try to link the cell to the tail cell */
        if (CAS (&tail->link, fifo_end(ff), cl))
            break;
        else
            /* tail was not pointing to the last cell, try to set tail to the next cell */
            CAS2 (&ff->tail, tail, ic, tail->link, ic+1);
    }
    /* enqeue is done, try to set tail to the enqueued cell */
    CAS2 (&ff->tail, tail, ic, cl, ic+1);
    msAtomicInc (&ff->count);
}
示例#4
0
/* 
   on intel architecture, the ABA problem is catched
   using oc (out count) and a CAS2
*/
lifocell* lfpop (lifo * lf)
{
	volatile  long oc;
	lifocell * volatile top;
	do {
		oc =  lf->oc;
		top = lf->top;
		if (!top) return 0;
	} while (!CAS2 (&lf->top, top, oc, top->link, oc+1));
	msAtomicDec (&lf->count);
	return top;
}
示例#5
0
 void enqueue(data_type val) {
     pointer_t tail, next;
     node_t* nd = new node_t();
     nd->value = val;
     //printf("%lld\n", val);
     while(true){
         tail = this->tail_; 
         next = tail.ptr->next;
         if (tail == this->tail_) {
             if(next.ptr == NULL) {
                 pointer_t new_pt(nd, next.tag+1);
                 if(CAS2(&(this->tail_.ptr->next), next, new_pt)){ 
                     break; // Enqueue done!
                 }
             }else {
                 pointer_t new_pt(next.ptr, tail.tag+1);
                 CAS2(&(this->tail_), tail, new_pt); 
             }
         }
     }
     pointer_t new_pt(nd, tail.tag+1);
     CAS2(&(this->tail_), tail, new_pt);
 }