139 lines
2.9 KiB
C
139 lines
2.9 KiB
C
/*
|
|
* File: queue.c
|
|
* Author: Robert I. Pitts <rip@cs.bu.edu>
|
|
* Last Modified: March 9, 2000
|
|
* Topic: Queue - Array Implementation
|
|
* ----------------------------------------------------------------
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include<pthread.h>
|
|
|
|
#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;
|
|
}
|
|
|