/*
 * @COPYRIGHT@
 * @COPYRIGHT@
 *
 * $RCSfile: scout_fifo.c,v $
 *
 * HISTORY
 * $Log: scout_fifo.c,v $
 * Revision 1.1  1997/09/19 20:25:11  bridges
 * Rearranged architecture files, build environment.
 * Added code to prevent blocking in many system calls.
 *
 * Revision 1.1  1996/10/02 13:38:47  davidm
 * Initial revision
 *
 */
/*
 * Concurrent single-reader/multi-writer FIFO queues.
 */
#include <assert.h>

#include <scout_fifo.h>
#include <scout_synch.h>


void
fifoInit (FIFO q)
{
    q->head = q->tail = (void *) 0;
}


void
fifoAppend (FIFO q, void * element)
{
    FIFOEl el = element;

    assert(element);

    el->next = 0;
    synchAtomicSequence(if (q->head) {
			    q->tail->next = el;
			} else {
			    q->head = el;
			}
			q->tail = el);
}

void
fifoAppendUnsafe (FIFO q, void * element)
{
    FIFOEl el = element;

    assert(element);

    el->next = 0;
    if (q->head) {
        q->tail->next = el;
    } else {
        q->head = el;
    }
    q->tail = el;
}


void *
fifoRemove (FIFO q)
{
    FIFOEl el = 0;

    if (!q->head) {
	/* cannot remove from empty fifo: */
	return 0;
    }

    el = q->head;
    if (el->next) {
	q->head = el->next;	/* more elements in the queue---no problem */
    } else {
	synchAtomicSequence(q->head = el->next);
    }
    return el;
}
