Source code of Windows XP (NT5)
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.

172 lines
3.5 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1993 - 1998
  3. Module Name:
  4. queue.c
  5. Abstract:
  6. Creates a simple Queue that works in Kernel Mode.
  7. Author:
  8. Robbie Harris (Hewlett-Packard) 22-May-1998
  9. Environment:
  10. Kernel mode
  11. Revision History :
  12. --*/
  13. #include "pch.h"
  14. void Queue_Create(Queue *pQueue, int size)
  15. {
  16. if (!pQueue)
  17. {
  18. ParDump(PARERRORS, ("Queue_Create: Queue is Bad"));
  19. return;
  20. }
  21. if (pQueue->theArray)
  22. Queue_Delete(pQueue);
  23. pQueue->theArray = (UCHAR *)ExAllocatePool(NonPagedPool, size);
  24. pQueue->max = size;
  25. pQueue->head = pQueue->tail = 0;
  26. }
  27. BOOLEAN Queue_Delete(Queue *pQueue)
  28. {
  29. if (!pQueue)
  30. {
  31. return FALSE;
  32. }
  33. if (pQueue->theArray) {
  34. ExFreePool(pQueue->theArray);
  35. pQueue->theArray = NULL;
  36. }
  37. pQueue->head = 0;
  38. pQueue->tail = 0;
  39. pQueue->max = 0;
  40. // NOTE: This can come back to haunt you!
  41. pQueue = 0;
  42. return TRUE;
  43. }
  44. BOOLEAN Queue_Dequeue(Queue *pQueue, PUCHAR data)
  45. {
  46. // Validity of pQueue is checked in Queue_IsEmpty proc.
  47. if (Queue_IsEmpty(pQueue))
  48. {
  49. ParDump(PARERRORS, ("Queue_Dequeue: Queue is Empty"));
  50. return FALSE;
  51. }
  52. *data = pQueue->theArray[pQueue->head++];
  53. return TRUE;
  54. }
  55. BOOLEAN Queue_Enqueue(Queue *pQueue, UCHAR data)
  56. {
  57. // Validity of pQueue is checked in Queue_IsFull proc.
  58. if (Queue_IsFull(pQueue)) {
  59. ParDump(PARERRORS, ("Queue_Enqueue: Queue is full. Data is lost"));
  60. return FALSE;
  61. } else {
  62. pQueue->theArray[pQueue->tail++] = data;
  63. }
  64. return TRUE;
  65. }
  66. /* Return TRUE if we were able to free some space in the Queue
  67. */
  68. BOOLEAN Queue_GarbageCollect(Queue *pQueue)
  69. {
  70. int iListSize;
  71. int i;
  72. if (!pQueue)
  73. {
  74. ParDump(PARERRORS, ("Queue_GarbageCollect: Queue is Bad"));
  75. return FALSE;
  76. }
  77. iListSize = pQueue->tail - pQueue->head;
  78. // Check to see if there is any free entries
  79. if (pQueue->head == 0 && pQueue->tail == pQueue->max)
  80. return FALSE;
  81. for (i = 0; i < iListSize; i++) {
  82. pQueue->theArray[i] = pQueue->theArray[pQueue->head+i];
  83. }
  84. pQueue->head = 0;
  85. pQueue->tail = iListSize;
  86. return TRUE;
  87. }
  88. //============================================================================
  89. // NAME: HPKQueue::IsEmpty()
  90. //
  91. // PARAMETERS: None
  92. //
  93. // RETURNS: True is Queue is empty or doesn't exist. Otherwise False.
  94. //
  95. //============================================================================
  96. BOOLEAN Queue_IsEmpty(Queue *pQueue)
  97. {
  98. if (!pQueue)
  99. {
  100. ParDump(PARERRORS, ("Queue_IsEmpty: Queue is Bad"));
  101. return TRUE;
  102. }
  103. if (pQueue->theArray) {
  104. return ((BOOLEAN) (pQueue->head == pQueue->tail));
  105. }
  106. ParDump(PARERRORS, ("Queue_IsEmpty: Queue->theArray is Bad"));
  107. return TRUE;
  108. }
  109. //============================================================================
  110. // NAME: HPKQueue::IsFull()
  111. //
  112. // PARAMETERS: None
  113. //
  114. // RETURNS: True is Queue is full or doesn't exist. Otherwise False.
  115. //
  116. //============================================================================
  117. BOOLEAN Queue_IsFull(Queue *pQueue)
  118. {
  119. if (!pQueue)
  120. {
  121. ParDump(PARERRORS, ("Queue_IsFull: Queue is Bad"));
  122. return TRUE;
  123. }
  124. if (pQueue->theArray) {
  125. if (pQueue->tail == pQueue->max)
  126. return !(Queue_GarbageCollect(pQueue));
  127. return FALSE;
  128. }
  129. ParDump(PARERRORS, ("Queue_IsFull: Queue->theArray is Bad"));
  130. return TRUE;
  131. }