2002-07-09 16:24:59 +04:00
|
|
|
/* Standard queue */
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
|
|
|
** Distributed under the terms of the NewOS License.
|
|
|
|
*/
|
2002-10-30 02:07:06 +03:00
|
|
|
|
2002-07-09 16:24:59 +04:00
|
|
|
#include <kernel.h>
|
|
|
|
#include <queue.h>
|
2002-10-30 02:07:06 +03:00
|
|
|
#include <malloc.h>
|
2002-07-12 02:21:16 +04:00
|
|
|
#include <errno.h>
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
typedef struct queue_element {
|
|
|
|
void *next;
|
|
|
|
} queue_element;
|
|
|
|
|
|
|
|
typedef struct queue_typed {
|
|
|
|
queue_element *head;
|
|
|
|
queue_element *tail;
|
|
|
|
int count;
|
|
|
|
} queue_typed;
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
int
|
|
|
|
queue_init(queue *q)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
q->head = q->tail = NULL;
|
|
|
|
q->count = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
int
|
|
|
|
queue_remove_item(queue *_q, void *e)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
queue_typed *q = (queue_typed *)_q;
|
|
|
|
queue_element *elem = (queue_element *)e;
|
|
|
|
queue_element *temp, *last = NULL;
|
|
|
|
|
|
|
|
temp = (queue_element *)q->head;
|
2002-10-30 02:07:06 +03:00
|
|
|
while (temp) {
|
|
|
|
if (temp == elem) {
|
|
|
|
if (last)
|
2002-07-09 16:24:59 +04:00
|
|
|
last->next = temp->next;
|
2002-10-30 02:07:06 +03:00
|
|
|
else
|
2002-07-09 16:24:59 +04:00
|
|
|
q->head = temp->next;
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
if (q->tail == temp)
|
2002-07-09 16:24:59 +04:00
|
|
|
q->tail = last;
|
|
|
|
q->count--;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
last = temp;
|
|
|
|
temp = temp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
int
|
|
|
|
queue_enqueue(queue *_q, void *e)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
queue_typed *q = (queue_typed *)_q;
|
|
|
|
queue_element *elem = (queue_element *)e;
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->tail == NULL) {
|
2002-07-09 16:24:59 +04:00
|
|
|
q->tail = elem;
|
|
|
|
q->head = elem;
|
|
|
|
} else {
|
|
|
|
q->tail->next = elem;
|
|
|
|
q->tail = elem;
|
|
|
|
}
|
|
|
|
elem->next = NULL;
|
|
|
|
q->count++;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
void *
|
|
|
|
queue_dequeue(queue *_q)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
queue_typed *q = (queue_typed *)_q;
|
|
|
|
queue_element *elem;
|
|
|
|
|
|
|
|
elem = q->head;
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->head != NULL)
|
2002-07-09 16:24:59 +04:00
|
|
|
q->head = q->head->next;
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->tail == elem)
|
2002-07-09 16:24:59 +04:00
|
|
|
q->tail = NULL;
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
if (elem != NULL)
|
2002-07-09 16:24:59 +04:00
|
|
|
q->count--;
|
|
|
|
|
|
|
|
return elem;
|
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
void *
|
|
|
|
queue_peek(queue *q)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
return q->head;
|
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
// #pragma mark -
|
2002-07-09 16:24:59 +04:00
|
|
|
/* fixed queue stuff */
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
int
|
|
|
|
fixed_queue_init(fixed_queue *q, int size)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-10-30 02:07:06 +03:00
|
|
|
if (size <= 0)
|
2002-07-12 02:21:16 +04:00
|
|
|
return EINVAL;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
q->table = malloc(size * sizeof(void *));
|
|
|
|
if (!q->table)
|
2002-07-12 02:21:16 +04:00
|
|
|
return ENOMEM;
|
2002-07-09 16:24:59 +04:00
|
|
|
q->head = 0;
|
|
|
|
q->tail = 0;
|
|
|
|
q->count = 0;
|
|
|
|
q->size = size;
|
|
|
|
|
2002-07-12 02:21:16 +04:00
|
|
|
return 0;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
fixed_queue_destroy(fixed_queue *q)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->table)
|
|
|
|
free(q->table);
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
int
|
|
|
|
fixed_queue_enqueue(fixed_queue *q, void *e)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->count == q->size)
|
2002-07-12 02:21:16 +04:00
|
|
|
return ENOMEM;
|
2002-07-09 16:24:59 +04:00
|
|
|
|
|
|
|
q->table[q->head++] = e;
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->head >= q->size)
|
|
|
|
q->head = 0;
|
2002-07-09 16:24:59 +04:00
|
|
|
q->count++;
|
|
|
|
|
2002-07-12 02:21:16 +04:00
|
|
|
return 0;
|
2002-07-09 16:24:59 +04:00
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
void *
|
|
|
|
fixed_queue_dequeue(fixed_queue *q)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
|
|
|
void *e;
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->count <= 0)
|
2002-07-09 16:24:59 +04:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
e = q->table[q->tail++];
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->tail >= q->size)
|
|
|
|
q->tail = 0;
|
2002-07-09 16:24:59 +04:00
|
|
|
q->count--;
|
|
|
|
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
2002-10-30 02:07:06 +03:00
|
|
|
|
|
|
|
void *
|
|
|
|
fixed_queue_peek(fixed_queue *q)
|
2002-07-09 16:24:59 +04:00
|
|
|
{
|
2002-10-30 02:07:06 +03:00
|
|
|
if (q->count <= 0)
|
2002-07-09 16:24:59 +04:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return q->table[q->tail];
|
|
|
|
}
|
|
|
|
|
|
|
|
|