Queue.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. #define WIN32_LEAN_AND_MEAN
  2. #include <windows.h>
  3. #include <winbase.h>
  4. #include "types.h"
  5. #include "debug.h"
  6. #include "memory.h"
  7. #include "queue.h"
  8. #define QUEUE_WRAPAROUND_FLAG 0xffffffffL
  9. /*-----------------------------------------------------------------------------
  10. Name : ResetQueue
  11. Description : Resets the Queue
  12. Inputs :
  13. Outputs :
  14. Return :
  15. ----------------------------------------------------------------------------*/
  16. void ResetQueue(Queue *queue)
  17. {
  18. queue->head = 0;
  19. queue->tail = 0;
  20. queue->num = 0;
  21. queue->totalsize = 0;
  22. queue->totaltotalsize = 0;
  23. queue->overruns = 0;
  24. }
  25. /*-----------------------------------------------------------------------------
  26. Name : InitQueue
  27. Description : Initializes the Queue
  28. Inputs :
  29. Outputs :
  30. Return :
  31. ----------------------------------------------------------------------------*/
  32. void InitQueue(Queue *queue,udword buffersize)
  33. {
  34. queue->mutex = (void *)CreateMutex(NULL,FALSE,NULL);
  35. dbgAssert(queue->mutex != NULL);
  36. queue->buffer = memAlloc(buffersize,"qbuffer",NonVolatile);
  37. queue->buffersize = buffersize;
  38. ResetQueue(queue);
  39. }
  40. /*-----------------------------------------------------------------------------
  41. Name : CloseQueue
  42. Description : Closes the Queue
  43. Inputs :
  44. Outputs :
  45. Return :
  46. ----------------------------------------------------------------------------*/
  47. void CloseQueue(Queue *queue)
  48. {
  49. CloseHandle((HANDLE)queue->mutex);
  50. queue->mutex = NULL;
  51. memFree(queue->buffer);
  52. queue->buffer = NULL;
  53. }
  54. /*-----------------------------------------------------------------------------
  55. Name : LockQueue
  56. Description : Locks the Queue for exclusive access
  57. Inputs :
  58. Outputs :
  59. Return :
  60. ----------------------------------------------------------------------------*/
  61. void LockQueue(Queue *queue)
  62. {
  63. DWORD result = WaitForSingleObject((HANDLE)queue->mutex,INFINITE);
  64. dbgAssert(result != WAIT_FAILED);
  65. }
  66. /*-----------------------------------------------------------------------------
  67. Name : UnLockQueue
  68. Description : Unlocks the queue, so other tasks can access it
  69. Inputs :
  70. Outputs :
  71. Return :
  72. ----------------------------------------------------------------------------*/
  73. void UnLockQueue(Queue *queue)
  74. {
  75. BOOL result = ReleaseMutex((HANDLE)queue->mutex);
  76. dbgAssert(result);
  77. }
  78. /*-----------------------------------------------------------------------------
  79. Name : Enqueue
  80. Description : Enqueue's data
  81. Inputs : packet, sizeofPacket
  82. Outputs :
  83. Return :
  84. ----------------------------------------------------------------------------*/
  85. void Enqueue(Queue *queue,ubyte *packet,udword sizeofPacket)
  86. {
  87. ubyte *writeto;
  88. udword sizeinQ = sizeof(udword) + sizeofPacket;
  89. dbgAssert(sizeofPacket > 0);
  90. if ((queue->totalsize+sizeinQ) > queue->buffersize)
  91. {
  92. queue->overruns++;
  93. return;
  94. }
  95. if ((queue->head+sizeinQ) > queue->buffersize)
  96. {
  97. // we are going over end of buffer, so wrap around
  98. writeto = &queue->buffer[queue->head];
  99. *((udword *)writeto) = QUEUE_WRAPAROUND_FLAG; // flag to indicate this is an invalid Q entry, and user should wrap to beginning
  100. queue->head = 0;
  101. }
  102. writeto = &queue->buffer[queue->head];
  103. *((udword *)writeto)++ = sizeofPacket;
  104. queue->head += sizeinQ;
  105. if ((queue->head+sizeof(udword)) > queue->buffersize)
  106. {
  107. queue->head = 0;
  108. }
  109. queue->totalsize += sizeinQ;
  110. queue->totaltotalsize += sizeinQ;
  111. memcpy(writeto,packet,sizeofPacket);
  112. queue->num++;
  113. }
  114. /*-----------------------------------------------------------------------------
  115. Name : Dequeue
  116. Description : Dequeue's data
  117. Inputs :
  118. Outputs : packet pointer
  119. Return : size of data returned
  120. ----------------------------------------------------------------------------*/
  121. udword Dequeue(Queue *queue,ubyte **packet)
  122. {
  123. ubyte *readfrom;
  124. udword sizeofPacket;
  125. udword sizeinQ;
  126. if (queue->num == 0)
  127. {
  128. return 0;
  129. }
  130. readfrom = &queue->buffer[queue->tail];
  131. if (*((udword *)readfrom) == QUEUE_WRAPAROUND_FLAG)
  132. {
  133. readfrom = &queue->buffer[0];
  134. queue->tail = 0;
  135. }
  136. sizeofPacket = *((udword *)readfrom)++;
  137. *packet = readfrom;
  138. sizeinQ = sizeof(udword) + sizeofPacket;
  139. queue->tail += sizeinQ;
  140. if ((queue->tail+sizeof(udword)) > queue->buffersize)
  141. {
  142. queue->tail = 0;
  143. }
  144. queue->totalsize -= sizeinQ;
  145. queue->num--;
  146. return sizeofPacket;
  147. }
  148. /*-----------------------------------------------------------------------------
  149. Name : Peekqueue
  150. Description : Peek at the next data in the queue without actually dequeueing
  151. Inputs :
  152. Outputs : packet pointer
  153. Return : size of data returned
  154. ----------------------------------------------------------------------------*/
  155. udword Peekqueue(Queue *queue,ubyte **packet)
  156. {
  157. ubyte *readfrom;
  158. udword sizeofPacket;
  159. //udword sizeinQ;
  160. if (queue->num == 0)
  161. {
  162. return 0;
  163. }
  164. readfrom = &queue->buffer[queue->tail];
  165. if (*((udword *)readfrom) == QUEUE_WRAPAROUND_FLAG)
  166. {
  167. readfrom = &queue->buffer[0];
  168. }
  169. sizeofPacket = *((udword *)readfrom)++;
  170. *packet = readfrom;
  171. return sizeofPacket;
  172. }