Esempio n. 1
0
//----------------------------------------------------------------
fifocell * fifoget (fifo * ff) 
{
	fifocell * volatile head;
	fifocell * next;
	short done = 0;
	
	do {
		LWARX (&ff->head);
        head = ff->head;				/* read the head cell */
		next = head->link;				/* read the next cell */
		/*
		  WARNING: the next pointer still needs to be checked before reading its value 
		*/
		if (head == ff->tail) {			/* is queue empty or tail falling behind? */
			if (head->link == fifo_end(ff) && STWCX (&ff->head, (void *)head, (void *)head)) /* is queue really 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               */
			CASLNE (&ff->tail, (void *)head, fifo_end(ff));
		}
		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 = STWCX (&ff->head, (void *)head, next);
		}
	} while (!done);
	msAtomicDec (&ff->count);
	if (head == &ff->dummy) {
		fifoput(ff,head);
		head = fifoget(ff);
	}
	return (fifocell *)head;
}
Esempio n. 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;
}
Esempio n. 3
0
//----------------------------------------------------------------
void fifoinit (fifo* ff)
{
    ff->count.value = 0;
    ff->oc = ff->ic = 0;
    ff->dummy.link = fifo_end(ff);
    ff->head = ff->tail = &ff->dummy;
}
Esempio n. 4
0
//----------------------------------------------------------------
void fifoput (fifo * ff, fifocell * cl) 
{
	fifocell * volatile tail;

    cl->link = fifo_end(ff);	/* set the cell next pointer to the end marker */
	while (1) {
		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 */
            CASLNE (&ff->tail, (void *)tail, fifo_end(ff));
        }
	} 
	CASLNE (&ff->tail, (void *)tail, fifo_end(ff));
	msAtomicInc (&ff->count);
}
Esempio n. 5
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);
}
Esempio n. 6
0
static void test2() {
  fifo_t *f1 = fifo_new(1024 * 4);
  int i;
  void *p;

  for (i = 0; i < 1023; i++) {
    p = fifo_alloc(f1, 13);
    assert(p);
    *(int *)p = i;
    fifo_put(f1, p, 13);

    p = fifo_get(f1, 13);
    assert(p);
    assert(*(int *)p == i);
    fifo_end(f1, p, 13);
  }

  assert(fifo_empty(f1));
}
Esempio n. 7
0
static void test3() {
  fifo_t *f1 = fifo_new(1024 * 4);
  int i;
  void *p;

  for (i = 0; i < 1023; i++) {
    p = fifo_alloc(f1, 13);
    assert(p);
    *(int *)p = i;
    fifo_put(f1, p, 13);

    p = fifo_extend(f1, p, 13, 13 * 2);
    assert(p);
    fifo_put(f1, p, 26);

    printf("%u %u\n", f1->pt, f1->gt);
    p = fifo_get(f1, 26);
    assert(p);
    assert(*(int *)p == i);
    fifo_end(f1, p, 26);
  }

  assert(fifo_empty(f1));
}