haiku/src/kernel/core/queue.c

153 lines
2.3 KiB
C
Raw Normal View History

/* Standard queue */
/*
** Copyright 2001, Travis Geiselbrecht. All rights reserved.
** Distributed under the terms of the NewOS License.
*/
#include <kernel.h>
#include <queue.h>
#include <memheap.h>
#include <Errors.h>
typedef struct queue_element {
void *next;
} queue_element;
typedef struct queue_typed {
queue_element *head;
queue_element *tail;
int count;
} queue_typed;
int queue_init(queue *q)
{
q->head = q->tail = NULL;
q->count = 0;
return 0;
}
int queue_remove_item(queue *_q, void *e)
{
queue_typed *q = (queue_typed *)_q;
queue_element *elem = (queue_element *)e;
queue_element *temp, *last = NULL;
temp = (queue_element *)q->head;
while(temp) {
if(temp == elem) {
if(last) {
last->next = temp->next;
} else {
q->head = temp->next;
}
if(q->tail == temp)
q->tail = last;
q->count--;
return 0;
}
last = temp;
temp = temp->next;
}
return -1;
}
int queue_enqueue(queue *_q, void *e)
{
queue_typed *q = (queue_typed *)_q;
queue_element *elem = (queue_element *)e;
if(q->tail == NULL) {
q->tail = elem;
q->head = elem;
} else {
q->tail->next = elem;
q->tail = elem;
}
elem->next = NULL;
q->count++;
return 0;
}
void *queue_dequeue(queue *_q)
{
queue_typed *q = (queue_typed *)_q;
queue_element *elem;
elem = q->head;
if(q->head != NULL)
q->head = q->head->next;
if(q->tail == elem)
q->tail = NULL;
if(elem != NULL)
q->count--;
return elem;
}
void *queue_peek(queue *q)
{
return q->head;
}
/* fixed queue stuff */
int fixed_queue_init(fixed_queue *q, int size)
{
if(size <= 0)
return ERR_INVALID_ARGS;
q->table = kmalloc(size * sizeof(void *));
if(!q->table)
return ERR_NO_MEMORY;
q->head = 0;
q->tail = 0;
q->count = 0;
q->size = size;
return B_NO_ERROR;
}
void fixed_queue_destroy(fixed_queue *q)
{
if(q->table)
kfree(q->table);
}
int fixed_queue_enqueue(fixed_queue *q, void *e)
{
if(q->count == q->size)
return ERR_NO_MEMORY;
q->table[q->head++] = e;
if(q->head >= q->size) q->head = 0;
q->count++;
return B_NO_ERROR;
}
void *fixed_queue_dequeue(fixed_queue *q)
{
void *e;
if(q->count <= 0)
return NULL;
e = q->table[q->tail++];
if(q->tail >= q->size) q->tail = 0;
q->count--;
return e;
}
void *fixed_queue_peek(fixed_queue *q)
{
if(q->count <= 0)
return NULL;
return q->table[q->tail];
}