1 /******************************************************************************/
3 /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom */
5 /* All rights reserved. */
7 /* This program is free software; you can redistribute it and/or modify */
8 /* it under the terms of the GNU General Public License as published by */
9 /* the Free Software Foundation, located in the file LICENSE. */
11 /* Queue functions. */
12 /* void QQ_InitQueue(PQQ_CONTAINER pQueue) */
13 /* char QQ_Full(PQQ_CONTAINER pQueue) */
14 /* char QQ_Empty(PQQ_CONTAINER pQueue) */
15 /* unsigned int QQ_GetSize(PQQ_CONTAINER pQueue) */
16 /* unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue) */
17 /* char QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
18 /* char QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
19 /* PQQ_ENTRY QQ_PopHead(PQQ_CONTAINER pQueue) */
20 /* PQQ_ENTRY QQ_PopTail(PQQ_CONTAINER pQueue) */
21 /* PQQ_ENTRY QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx) */
22 /* PQQ_ENTRY QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx) */
26 /* 02/25/00 Hav Khauv Initial version. */
27 /******************************************************************************/
34 /******************************************************************************/
35 /* Queue definitions. */
36 /******************************************************************************/
38 /* Entry for queueing. */
39 typedef void *PQQ_ENTRY;
42 /* Queue header -- base type. */
49 } QQ_CONTAINER, *PQQ_CONTAINER;
52 /* Declare queue type macro. */
53 #define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE) \
56 QQ_CONTAINER Container; \
57 PQQ_ENTRY EntryBuffer[_QUEUE_SIZE]; \
58 } _QUEUE_TYPE, *P##_QUEUE_TYPE
62 /******************************************************************************/
63 /* Compilation switches. */
64 /******************************************************************************/
67 #undef QQ_NO_OVERFLOW_CHECK
68 #undef QQ_NO_UNDERFLOW_CHECK
77 #endif /* QQ_NO_INLINE */
81 /******************************************************************************/
85 /******************************************************************************/
89 unsigned int QueueSize) {
92 pQueue->Size = QueueSize+1;
93 MM_ATOMIC_SET(&pQueue->EntryCnt, 0);
98 /******************************************************************************/
102 /******************************************************************************/
105 PQQ_CONTAINER pQueue) {
106 unsigned int NewHead;
108 NewHead = (pQueue->Head + 1) % pQueue->Size;
110 return(NewHead == pQueue->Tail);
115 /******************************************************************************/
119 /******************************************************************************/
122 PQQ_CONTAINER pQueue) {
123 return(pQueue->Head == pQueue->Tail);
128 /******************************************************************************/
132 /******************************************************************************/
133 __inline static unsigned int
135 PQQ_CONTAINER pQueue) {
141 /******************************************************************************/
145 /******************************************************************************/
146 __inline static unsigned int
148 PQQ_CONTAINER pQueue) {
149 return MM_ATOMIC_READ(&pQueue->EntryCnt);
150 } /* QQ_GetEntryCnt */
154 /******************************************************************************/
158 /* TRUE entry was added successfully. */
159 /* FALSE queue is full. */
160 /******************************************************************************/
163 PQQ_CONTAINER pQueue,
167 Head = (pQueue->Head + 1) % pQueue->Size;
169 #if !defined(QQ_NO_OVERFLOW_CHECK)
170 if(Head == pQueue->Tail) {
173 #endif /* QQ_NO_OVERFLOW_CHECK */
175 pQueue->Array[pQueue->Head] = pEntry;
178 MM_ATOMIC_INC(&pQueue->EntryCnt);
185 /******************************************************************************/
189 /* TRUE entry was added successfully. */
190 /* FALSE queue is full. */
191 /******************************************************************************/
194 PQQ_CONTAINER pQueue,
204 #if !defined(QQ_NO_OVERFLOW_CHECK)
205 if(Tail == pQueue->Head) {
208 #endif /* QQ_NO_OVERFLOW_CHECK */
210 pQueue->Array[Tail] = pEntry;
213 MM_ATOMIC_INC(&pQueue->EntryCnt);
220 /******************************************************************************/
224 /******************************************************************************/
225 __inline static PQQ_ENTRY
227 PQQ_CONTAINER pQueue) {
236 #if !defined(QQ_NO_UNDERFLOW_CHECK)
238 return (PQQ_ENTRY) 0;
240 #endif /* QQ_NO_UNDERFLOW_CHECK */
247 Entry = pQueue->Array[Head];
250 MM_ATOMIC_DEC(&pQueue->EntryCnt);
257 /******************************************************************************/
261 /******************************************************************************/
262 __inline static PQQ_ENTRY
264 PQQ_CONTAINER pQueue) {
273 #if !defined(QQ_NO_UNDERFLOW_CHECK)
275 return (PQQ_ENTRY) 0;
277 #endif /* QQ_NO_UNDERFLOW_CHECK */
279 Entry = pQueue->Array[Tail];
281 pQueue->Tail = (Tail + 1) % pQueue->Size;
282 MM_ATOMIC_DEC(&pQueue->EntryCnt);
289 /******************************************************************************/
293 /******************************************************************************/
294 __inline static PQQ_ENTRY
296 PQQ_CONTAINER pQueue,
299 if(Idx >= (unsigned int) MM_ATOMIC_READ(&pQueue->EntryCnt))
301 return (PQQ_ENTRY) 0;
304 if(pQueue->Head > Idx)
306 Idx = pQueue->Head - Idx;
310 Idx = pQueue->Size - (Idx - pQueue->Head);
314 return pQueue->Array[Idx];
319 /******************************************************************************/
323 /******************************************************************************/
324 __inline static PQQ_ENTRY
326 PQQ_CONTAINER pQueue,
329 if(Idx >= (unsigned int) MM_ATOMIC_READ(&pQueue->EntryCnt))
331 return (PQQ_ENTRY) 0;
335 if(Idx >= pQueue->Size)
337 Idx = Idx - pQueue->Size;
340 return pQueue->Array[Idx];
343 #endif /* QQ_USE_MACROS */