2 /******************************************************************************/
4 /* Broadcom BCM4400 Linux Network Driver, Copyright (c) 2002 Broadcom */
6 /* All rights reserved. */
8 /* This program is free software; you can redistribute it and/or modify */
9 /* it under the terms of the GNU General Public License as published by */
10 /* the Free Software Foundation, located in the file LICENSE. */
12 /* Queue functions. */
13 /* void QQ_InitQueue(PQQ_CONTAINER pQueue) */
14 /* char QQ_Full(PQQ_CONTAINER pQueue) */
15 /* char QQ_Empty(PQQ_CONTAINER pQueue) */
16 /* unsigned int QQ_GetSize(PQQ_CONTAINER pQueue) */
17 /* unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue) */
18 /* char QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
19 /* char QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
20 /* PQQ_ENTRY QQ_PopHead(PQQ_CONTAINER pQueue) */
21 /* PQQ_ENTRY QQ_PopTail(PQQ_CONTAINER pQueue) */
22 /* PQQ_ENTRY QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx) */
23 /* PQQ_ENTRY QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx) */
27 /* 02/25/00 Hav Khauv Initial version. */
28 /******************************************************************************/
35 /******************************************************************************/
36 /* Queue definitions. */
37 /******************************************************************************/
39 /* Entry for queueing. */
40 typedef void *PQQ_ENTRY
;
43 /* Queue header -- base type. */
50 } QQ_CONTAINER
, *PQQ_CONTAINER
;
53 /* Declare queue type macro. */
54 #define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE) \
57 QQ_CONTAINER Container; \
58 PQQ_ENTRY EntryBuffer[_QUEUE_SIZE]; \
59 } _QUEUE_TYPE, *P##_QUEUE_TYPE
63 /******************************************************************************/
64 /* Compilation switches. */
65 /******************************************************************************/
68 #undef QQ_NO_OVERFLOW_CHECK
69 #undef QQ_NO_UNDERFLOW_CHECK
78 #endif /* QQ_NO_INLINE */
82 /******************************************************************************/
86 /******************************************************************************/
90 unsigned int QueueSize
) {
93 pQueue
->Size
= QueueSize
+1;
94 MM_ATOMIC_SET(&pQueue
->EntryCnt
, 0);
99 /******************************************************************************/
103 /******************************************************************************/
106 PQQ_CONTAINER pQueue
) {
107 unsigned int NewHead
;
109 NewHead
= (pQueue
->Head
+ 1) % pQueue
->Size
;
111 return(NewHead
== pQueue
->Tail
);
116 /******************************************************************************/
120 /******************************************************************************/
123 PQQ_CONTAINER pQueue
) {
124 return(pQueue
->Head
== pQueue
->Tail
);
129 /******************************************************************************/
133 /******************************************************************************/
134 __inline
static unsigned int
136 PQQ_CONTAINER pQueue
) {
142 /******************************************************************************/
146 /******************************************************************************/
147 __inline
static unsigned int
149 PQQ_CONTAINER pQueue
) {
150 return MM_ATOMIC_READ(&pQueue
->EntryCnt
);
151 } /* QQ_GetEntryCnt */
155 /******************************************************************************/
159 /* TRUE entry was added successfully. */
160 /* FALSE queue is full. */
161 /******************************************************************************/
164 PQQ_CONTAINER pQueue
,
168 Head
= (pQueue
->Head
+ 1) % pQueue
->Size
;
170 #if !defined(QQ_NO_OVERFLOW_CHECK)
171 if(Head
== pQueue
->Tail
) {
174 #endif /* QQ_NO_OVERFLOW_CHECK */
176 pQueue
->Array
[pQueue
->Head
] = pEntry
;
179 MM_ATOMIC_INC(&pQueue
->EntryCnt
);
186 /******************************************************************************/
190 /* TRUE entry was added successfully. */
191 /* FALSE queue is full. */
192 /******************************************************************************/
195 PQQ_CONTAINER pQueue
,
205 #if !defined(QQ_NO_OVERFLOW_CHECK)
206 if(Tail
== pQueue
->Head
) {
209 #endif /* QQ_NO_OVERFLOW_CHECK */
211 pQueue
->Array
[Tail
] = pEntry
;
214 MM_ATOMIC_INC(&pQueue
->EntryCnt
);
221 /******************************************************************************/
225 /******************************************************************************/
226 __inline
static PQQ_ENTRY
228 PQQ_CONTAINER pQueue
) {
234 #if !defined(QQ_NO_UNDERFLOW_CHECK)
235 if(Head
== pQueue
->Tail
) {
236 return (PQQ_ENTRY
) 0;
238 #endif /* QQ_NO_UNDERFLOW_CHECK */
245 Entry
= pQueue
->Array
[Head
];
248 MM_ATOMIC_DEC(&pQueue
->EntryCnt
);
255 /******************************************************************************/
259 /******************************************************************************/
260 __inline
static PQQ_ENTRY
262 PQQ_CONTAINER pQueue
) {
268 #if !defined(QQ_NO_UNDERFLOW_CHECK)
269 if(Tail
== pQueue
->Head
) {
270 return (PQQ_ENTRY
) 0;
272 #endif /* QQ_NO_UNDERFLOW_CHECK */
274 Entry
= pQueue
->Array
[Tail
];
276 pQueue
->Tail
= (Tail
+ 1) % pQueue
->Size
;
277 MM_ATOMIC_DEC(&pQueue
->EntryCnt
);
284 /******************************************************************************/
288 /******************************************************************************/
289 __inline
static PQQ_ENTRY
291 PQQ_CONTAINER pQueue
,
294 if(Idx
>= MM_ATOMIC_READ(&pQueue
->EntryCnt
))
296 return (PQQ_ENTRY
) 0;
299 if(pQueue
->Head
> Idx
)
301 Idx
= pQueue
->Head
- Idx
;
305 Idx
= pQueue
->Size
- (Idx
- pQueue
->Head
);
309 return pQueue
->Array
[Idx
];
314 /******************************************************************************/
318 /******************************************************************************/
319 __inline
static PQQ_ENTRY
321 PQQ_CONTAINER pQueue
,
324 if(Idx
>= MM_ATOMIC_READ(&pQueue
->EntryCnt
))
326 return (PQQ_ENTRY
) 0;
330 if(Idx
>= pQueue
->Size
)
332 Idx
= Idx
- pQueue
->Size
;
335 return pQueue
->Array
[Idx
];
338 #endif /* QQ_USE_MACROS */