/* * File: queue.c * Author: Robert I. Pitts * Last Modified: March 9, 2000 * Topic: Queue - Array Implementation * ---------------------------------------------------------------- */ #include #include #include #include "utils_queue.h" /* * struct queueCDT gives the implementation of a queue. * It holds the information that we need for each queue. */ typedef struct queueCDT { queueElementT *contents; int front; int count; int elem_size; pthread_rwlock_t queueRWLock; }queueCDT; queueADT QueueCreate(const int elem_size) { queueADT queue; queue = (queueADT)malloc(sizeof(queueCDT)); if(queue == NULL) { fprintf(stderr, "Insufficient Memory for new Queue.\n"); return NULL; /* Exit program, returning error code. */ } queue->contents = (queueElementT*)malloc(elem_size * sizeof(queueElementT)); if(queue == NULL) { fprintf(stderr, "Insufficient Memory for QueueElems.\n"); return NULL; /* Exit program, returning error code. */ } queue->front = 0; queue->count = 0; queue->elem_size = elem_size; pthread_rwlock_init(&(queue->queueRWLock), NULL); return queue; } void QueueDestroy(queueADT queue) { free(queue->contents); free(queue); } int QueueEnter(queueADT queue, queueElementT element) { int newElementIndex; pthread_rwlock_wrlock(&queue->queueRWLock); if (queue->count >= queue->elem_size) { fprintf(stderr, "QueueEnter on Full Queue.\n"); pthread_rwlock_unlock(&queue->queueRWLock); return ERROR_QUEUE; /* Exit program, returning error code. */ } /* * Calculate index at which to put * next element. */ newElementIndex = (queue->front + queue->count) % queue->elem_size; queue->contents[newElementIndex] = element; queue->count++; pthread_rwlock_unlock(&queue->queueRWLock); return SUCCESS_QUEUE; } queueElementT QueueDelete(queueADT queue) { queueElementT oldElement; pthread_rwlock_wrlock(&queue->queueRWLock); if (queue->count <= 0) { fprintf(stderr, "QueueDelete on Empty Queue.\n"); pthread_rwlock_unlock(&queue->queueRWLock); return NULL; /* Exit program, returning error code. */ } /* Save the element so we can return it. */ oldElement = queue->contents[queue->front]; /* * Advance the index of the front, * making sure it wraps around the * array properly. */ queue->front++; queue->front %= queue->elem_size; queue->count--; pthread_rwlock_unlock(&queue->queueRWLock); return oldElement; } int QueueIsEmpty(queueADT queue) { int rc; pthread_rwlock_rdlock(&queue->queueRWLock); rc = queue->count <= 0; pthread_rwlock_unlock(&queue->queueRWLock); return rc; } int QueueIsFull(queueADT queue) { int rc; pthread_rwlock_rdlock(&queue->queueRWLock); rc = queue->count >= queue->elem_size; pthread_rwlock_unlock(&queue->queueRWLock); return rc; }