mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
5.5 KiB
299 lines
5.5 KiB
/*++
|
|
|
|
Copyright (c) 1995 Intel Corp
|
|
|
|
Module Name:
|
|
|
|
queue.h
|
|
|
|
Abstract:
|
|
|
|
Implementation of functions supplied by this queue manager module.
|
|
|
|
Author:
|
|
|
|
Michael Grafton
|
|
|
|
--*/
|
|
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
#include "queue.h"
|
|
|
|
|
|
|
|
|
|
PQUEUE
|
|
QCreate(void)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Creates a new QUEUE, initializes it, and returns it. Returns NULL
|
|
if memory cannot be allocated in the heap.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
NULL if memory allocation fails; else a pointer to a new queue.
|
|
|
|
--*/
|
|
{
|
|
|
|
PQUEUE Queue; // points to the new queue
|
|
|
|
// Allocate space for a new queue.
|
|
Queue = (PQUEUE)malloc(sizeof(QUEUE));
|
|
if (Queue != NULL){
|
|
|
|
// Initialize the new queue.
|
|
Queue->Head = Q_NULL;
|
|
Queue->Tail = Q_NULL;
|
|
InitializeCriticalSection(&Queue->CrSec);
|
|
}
|
|
return(Queue);
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
QFree(PQUEUE Queue)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function removes any items left on the queue, frees them, and
|
|
then frees the queue itself.
|
|
|
|
Arguments:
|
|
|
|
Queue -- Pointer to the queue to free.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
|
|
LPVOID Object; // points to objects we pull off the queue
|
|
|
|
EnterCriticalSection(&Queue->CrSec);
|
|
|
|
// Free everything on the queue.
|
|
Object = QRemove(Queue);
|
|
while (Object) {
|
|
free(Object);
|
|
Object = QRemove(Queue);
|
|
}
|
|
|
|
LeaveCriticalSection(&Queue->CrSec);
|
|
|
|
// Free the queue itself.
|
|
free(Queue);
|
|
}
|
|
|
|
|
|
|
|
|
|
LPVOID
|
|
QRemove(PQUEUE Queue)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function dequeues one object from Queue and returns a generic
|
|
pointer to the object. It is up to the calling function to know
|
|
the size and type of the object dequeued.
|
|
|
|
Arguments:
|
|
|
|
Queue -- The queue from which to dequeue the object.
|
|
|
|
Return Value:
|
|
|
|
NULL if the queue is empty; else, a pointer to the dequeued object.
|
|
|
|
--*/
|
|
{
|
|
|
|
LPVOID Data; // points to the object we pull off the queue
|
|
|
|
EnterCriticalSection(&Queue->CrSec);
|
|
|
|
if (Queue->Head == Q_NULL){
|
|
|
|
// If the queue is empty, we will return NULL.
|
|
Data = NULL;
|
|
|
|
} else {
|
|
|
|
// Get the pointer, NULL it in the QueueArray.
|
|
Data = Queue->QueueArray[Queue->Head];
|
|
Queue->QueueArray[Queue->Head] = NULL;
|
|
|
|
// Check to see if we've just emptied the queue; if so, set
|
|
// the Head and Tail indices to Q_NULL. If not, set the Head
|
|
// index to the right value.
|
|
if (Queue->Head == Queue->Tail) {
|
|
Queue->Head = Queue->Tail = Q_NULL;
|
|
} else {
|
|
Queue->Head = (Queue->Head + 1) % MAX_QUEUE_SIZE;
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection(&Queue->CrSec);
|
|
return(Data);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
QInsert(
|
|
PQUEUE Queue,
|
|
LPVOID Object)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function enqueues one item into Queue, if there is room for
|
|
it.
|
|
|
|
Arguments:
|
|
|
|
Queue -- The queue onto which to enqueue Object.
|
|
|
|
Object -- A void pointer to the object being enqueued.
|
|
|
|
Return Value:
|
|
|
|
TRUE -- The object was successfully enqueued.
|
|
|
|
FALSE -- There were too many items already in the queue; one item
|
|
must be removed in order to insert another.
|
|
|
|
--*/
|
|
{
|
|
BOOL ReturnValue; // holds the return value
|
|
|
|
EnterCriticalSection(&Queue->CrSec);
|
|
|
|
// If the queue is full, set the return value to FALSE and do
|
|
// nothing; if not, update the indices appropriately and set the
|
|
// return value to TRUE.
|
|
if(((Queue->Tail + 1) % MAX_QUEUE_SIZE == Queue->Head)
|
|
&& (Queue->Head != Q_NULL)) {
|
|
|
|
ReturnValue = FALSE;
|
|
|
|
} else {
|
|
|
|
Queue->Tail = (Queue->Tail + 1) % MAX_QUEUE_SIZE;
|
|
Queue->QueueArray[Queue->Tail] = Object;
|
|
if (Queue->Head == Q_NULL){
|
|
Queue->Head = 0;
|
|
}
|
|
ReturnValue = TRUE;
|
|
}
|
|
|
|
LeaveCriticalSection(&Queue->CrSec);
|
|
return(ReturnValue);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
QInsertAtHead(
|
|
PQUEUE Queue,
|
|
LPVOID Object)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function inserts one item at the HEAD of the queue. Of
|
|
course, this violates queue semantics...but this can be useful at
|
|
times.
|
|
|
|
Arguments:
|
|
|
|
Queue -- The queue into which to insert Object.
|
|
|
|
Object -- A void pointer to the object being inserted.
|
|
|
|
Return Value:
|
|
|
|
TRUE -- The object was successfully inserted at the head of the
|
|
queue.
|
|
|
|
FALSE -- There were too many items already in the queue; one item
|
|
must be removed in order to insert another.
|
|
|
|
--*/
|
|
{
|
|
|
|
BOOL ReturnValue; // holds the return value
|
|
|
|
EnterCriticalSection(&Queue->CrSec);
|
|
|
|
// If the queue is full, set the return value to FALSE and do
|
|
// nothing; if not, update the indices appropriately and set the
|
|
// return value to TRUE.
|
|
if((Queue->Tail == Queue->Head) && (Queue->Head != Q_NULL)){
|
|
|
|
ReturnValue = FALSE;
|
|
|
|
} else {
|
|
|
|
if (Queue->Head == Q_NULL) {
|
|
|
|
// The queue was empty, so just use QInsert.
|
|
QInsert(Queue, Object);
|
|
}
|
|
|
|
if (Queue->Head == 0) {
|
|
Queue->Head = MAX_QUEUE_SIZE - 1;
|
|
} else {
|
|
Queue->Head = Queue->Head - 1;
|
|
}
|
|
|
|
Queue->QueueArray[Queue->Head] = Object;
|
|
ReturnValue = TRUE;
|
|
}
|
|
|
|
LeaveCriticalSection(&Queue->CrSec);
|
|
return(ReturnValue);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
QIsEmpty(PQUEUE Queue)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This function tells the caller if the queue in question contains
|
|
any items.
|
|
|
|
Arguments:
|
|
|
|
Queue -- The queue which we want to query.
|
|
|
|
Return Value:
|
|
|
|
TRUE -- The queue is empty.
|
|
|
|
FALSE -- The queue contains at least one item.
|
|
|
|
--*/
|
|
{
|
|
return(Queue->Head == Q_NULL ? TRUE : FALSE);
|
|
}
|