173 lines
3.5 KiB
C
173 lines
3.5 KiB
C
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1993 - 1998
|
|
|
|
Module Name:
|
|
|
|
queue.c
|
|
|
|
Abstract:
|
|
|
|
Creates a simple Queue that works in Kernel Mode.
|
|
|
|
Author:
|
|
|
|
Robbie Harris (Hewlett-Packard) 22-May-1998
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History :
|
|
|
|
--*/
|
|
#include "pch.h"
|
|
|
|
void Queue_Create(Queue *pQueue, int size)
|
|
{
|
|
if (!pQueue)
|
|
{
|
|
ParDump(PARERRORS, ("Queue_Create: Queue is Bad"));
|
|
return;
|
|
}
|
|
|
|
if (pQueue->theArray)
|
|
Queue_Delete(pQueue);
|
|
|
|
pQueue->theArray = (UCHAR *)ExAllocatePool(NonPagedPool, size);
|
|
pQueue->max = size;
|
|
pQueue->head = pQueue->tail = 0;
|
|
}
|
|
|
|
BOOLEAN Queue_Delete(Queue *pQueue)
|
|
{
|
|
if (!pQueue)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (pQueue->theArray) {
|
|
|
|
ExFreePool(pQueue->theArray);
|
|
pQueue->theArray = NULL;
|
|
}
|
|
|
|
pQueue->head = 0;
|
|
pQueue->tail = 0;
|
|
pQueue->max = 0;
|
|
// NOTE: This can come back to haunt you!
|
|
pQueue = 0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN Queue_Dequeue(Queue *pQueue, PUCHAR data)
|
|
{
|
|
// Validity of pQueue is checked in Queue_IsEmpty proc.
|
|
if (Queue_IsEmpty(pQueue))
|
|
{
|
|
ParDump(PARERRORS, ("Queue_Dequeue: Queue is Empty"));
|
|
return FALSE;
|
|
}
|
|
|
|
*data = pQueue->theArray[pQueue->head++];
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN Queue_Enqueue(Queue *pQueue, UCHAR data)
|
|
{
|
|
// Validity of pQueue is checked in Queue_IsFull proc.
|
|
if (Queue_IsFull(pQueue)) {
|
|
|
|
ParDump(PARERRORS, ("Queue_Enqueue: Queue is full. Data is lost"));
|
|
return FALSE;
|
|
|
|
} else {
|
|
pQueue->theArray[pQueue->tail++] = data;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/* Return TRUE if we were able to free some space in the Queue
|
|
*/
|
|
BOOLEAN Queue_GarbageCollect(Queue *pQueue)
|
|
{
|
|
int iListSize;
|
|
int i;
|
|
|
|
if (!pQueue)
|
|
{
|
|
ParDump(PARERRORS, ("Queue_GarbageCollect: Queue is Bad"));
|
|
return FALSE;
|
|
}
|
|
|
|
iListSize = pQueue->tail - pQueue->head;
|
|
|
|
// Check to see if there is any free entries
|
|
if (pQueue->head == 0 && pQueue->tail == pQueue->max)
|
|
return FALSE;
|
|
|
|
for (i = 0; i < iListSize; i++) {
|
|
|
|
pQueue->theArray[i] = pQueue->theArray[pQueue->head+i];
|
|
}
|
|
|
|
pQueue->head = 0;
|
|
pQueue->tail = iListSize;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//============================================================================
|
|
// NAME: HPKQueue::IsEmpty()
|
|
//
|
|
// PARAMETERS: None
|
|
//
|
|
// RETURNS: True is Queue is empty or doesn't exist. Otherwise False.
|
|
//
|
|
//============================================================================
|
|
BOOLEAN Queue_IsEmpty(Queue *pQueue)
|
|
{
|
|
if (!pQueue)
|
|
{
|
|
ParDump(PARERRORS, ("Queue_IsEmpty: Queue is Bad"));
|
|
return TRUE;
|
|
}
|
|
|
|
if (pQueue->theArray) {
|
|
|
|
return ((BOOLEAN) (pQueue->head == pQueue->tail));
|
|
}
|
|
ParDump(PARERRORS, ("Queue_IsEmpty: Queue->theArray is Bad"));
|
|
return TRUE;
|
|
}
|
|
|
|
//============================================================================
|
|
// NAME: HPKQueue::IsFull()
|
|
//
|
|
// PARAMETERS: None
|
|
//
|
|
// RETURNS: True is Queue is full or doesn't exist. Otherwise False.
|
|
//
|
|
//============================================================================
|
|
BOOLEAN Queue_IsFull(Queue *pQueue)
|
|
{
|
|
if (!pQueue)
|
|
{
|
|
ParDump(PARERRORS, ("Queue_IsFull: Queue is Bad"));
|
|
return TRUE;
|
|
}
|
|
|
|
if (pQueue->theArray) {
|
|
|
|
if (pQueue->tail == pQueue->max)
|
|
return !(Queue_GarbageCollect(pQueue));
|
|
|
|
return FALSE;
|
|
}
|
|
ParDump(PARERRORS, ("Queue_IsFull: Queue->theArray is Bad"));
|
|
return TRUE;
|
|
}
|
|
|