| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- /******************************************************************************/
- /* */
- /* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 - 2004 Broadcom */
- /* Corporation. */
- /* All rights reserved. */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation, located in the file LICENSE. */
- /* */
- /* Queue functions. */
- /* void QQ_InitQueue(PQQ_CONTAINER pQueue) */
- /* char QQ_Full(PQQ_CONTAINER pQueue) */
- /* char QQ_Empty(PQQ_CONTAINER pQueue) */
- /* unsigned int QQ_GetSize(PQQ_CONTAINER pQueue) */
- /* unsigned int QQ_GetEntryCnt(PQQ_CONTAINER pQueue) */
- /* char QQ_PushHead(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
- /* char QQ_PushTail(PQQ_CONTAINER pQueue, PQQ_ENTRY pEntry) */
- /* PQQ_ENTRY QQ_PopHead(PQQ_CONTAINER pQueue) */
- /* PQQ_ENTRY QQ_PopTail(PQQ_CONTAINER pQueue) */
- /* PQQ_ENTRY QQ_GetHead(PQQ_CONTAINER pQueue, unsigned int Idx) */
- /* PQQ_ENTRY QQ_GetTail(PQQ_CONTAINER pQueue, unsigned int Idx) */
- /* */
- /* */
- /* History: */
- /* 02/25/00 Hav Khauv Initial version. */
- /******************************************************************************/
- #ifndef BCM_QUEUE_H
- #define BCM_QUEUE_H
- /******************************************************************************/
- /* Queue definitions. */
- /******************************************************************************/
- /* Entry for queueing. */
- typedef void *PQQ_ENTRY;
- /* Queue header -- base type. */
- typedef struct {
- unsigned int Head;
- unsigned int Tail;
- unsigned int Size;
- MM_ATOMIC_T EntryCnt;
- PQQ_ENTRY Array[1];
- } QQ_CONTAINER, *PQQ_CONTAINER;
- /* Declare queue type macro. */
- #define DECLARE_QUEUE_TYPE(_QUEUE_TYPE, _QUEUE_SIZE) \
- \
- typedef struct { \
- QQ_CONTAINER Container; \
- PQQ_ENTRY EntryBuffer[_QUEUE_SIZE]; \
- } _QUEUE_TYPE, *P##_QUEUE_TYPE
- /******************************************************************************/
- /* Compilation switches. */
- /******************************************************************************/
- #if DBG
- #undef QQ_NO_OVERFLOW_CHECK
- #undef QQ_NO_UNDERFLOW_CHECK
- #endif /* DBG */
- #ifdef QQ_USE_MACROS
- /* notdone */
- #else
- #ifdef QQ_NO_INLINE
- #define __inline
- #endif /* QQ_NO_INLINE */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static void
- QQ_InitQueue(
- PQQ_CONTAINER pQueue,
- unsigned int QueueSize) {
- pQueue->Head = 0;
- pQueue->Tail = 0;
- pQueue->Size = QueueSize+1;
- MM_ATOMIC_SET(&pQueue->EntryCnt, 0);
- } /* QQ_InitQueue */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static char
- QQ_Full(
- PQQ_CONTAINER pQueue) {
- unsigned int NewHead;
- NewHead = (pQueue->Head + 1) % pQueue->Size;
- return(NewHead == pQueue->Tail);
- } /* QQ_Full */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static char
- QQ_Empty(
- PQQ_CONTAINER pQueue) {
- return(pQueue->Head == pQueue->Tail);
- } /* QQ_Empty */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static unsigned int
- QQ_GetSize(
- PQQ_CONTAINER pQueue) {
- return pQueue->Size;
- } /* QQ_GetSize */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static unsigned int
- QQ_GetEntryCnt(
- PQQ_CONTAINER pQueue) {
- return MM_ATOMIC_READ(&pQueue->EntryCnt);
- } /* QQ_GetEntryCnt */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /* TRUE entry was added successfully. */
- /* FALSE queue is full. */
- /******************************************************************************/
- __inline static char
- QQ_PushHead(
- PQQ_CONTAINER pQueue,
- PQQ_ENTRY pEntry) {
- unsigned int Head;
- Head = (pQueue->Head + 1) % pQueue->Size;
- #if !defined(QQ_NO_OVERFLOW_CHECK)
- if(Head == pQueue->Tail) {
- return 0;
- } /* if */
- #endif /* QQ_NO_OVERFLOW_CHECK */
- pQueue->Array[pQueue->Head] = pEntry;
- MM_WMB();
- pQueue->Head = Head;
- MM_ATOMIC_INC(&pQueue->EntryCnt);
- return -1;
- } /* QQ_PushHead */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /* TRUE entry was added successfully. */
- /* FALSE queue is full. */
- /******************************************************************************/
- __inline static char
- QQ_PushTail(
- PQQ_CONTAINER pQueue,
- PQQ_ENTRY pEntry) {
- unsigned int Tail;
- Tail = pQueue->Tail;
- if(Tail == 0) {
- Tail = pQueue->Size;
- } /* if */
- Tail--;
- #if !defined(QQ_NO_OVERFLOW_CHECK)
- if(Tail == pQueue->Head) {
- return 0;
- } /* if */
- #endif /* QQ_NO_OVERFLOW_CHECK */
- pQueue->Array[Tail] = pEntry;
- MM_WMB();
- pQueue->Tail = Tail;
- MM_ATOMIC_INC(&pQueue->EntryCnt);
- return -1;
- } /* QQ_PushTail */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static PQQ_ENTRY
- QQ_PopHead(
- PQQ_CONTAINER pQueue) {
- unsigned int Head;
- unsigned int Tail;
- PQQ_ENTRY Entry;
- Head = pQueue->Head;
- Tail = pQueue->Tail;
- MM_MB();
- #if !defined(QQ_NO_UNDERFLOW_CHECK)
- if(Head == Tail) {
- return (PQQ_ENTRY) 0;
- } /* if */
- #endif /* QQ_NO_UNDERFLOW_CHECK */
- if(Head == 0) {
- Head = pQueue->Size;
- } /* if */
- Head--;
- Entry = pQueue->Array[Head];
- MM_MB();
- pQueue->Head = Head;
- MM_ATOMIC_DEC(&pQueue->EntryCnt);
- return Entry;
- } /* QQ_PopHead */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static PQQ_ENTRY
- QQ_PopTail(
- PQQ_CONTAINER pQueue) {
- unsigned int Head;
- unsigned int Tail;
- PQQ_ENTRY Entry;
- Head = pQueue->Head;
- Tail = pQueue->Tail;
- MM_MB();
- #if !defined(QQ_NO_UNDERFLOW_CHECK)
- if(Tail == Head) {
- return (PQQ_ENTRY) 0;
- } /* if */
- #endif /* QQ_NO_UNDERFLOW_CHECK */
- Entry = pQueue->Array[Tail];
- MM_MB();
- pQueue->Tail = (Tail + 1) % pQueue->Size;
- MM_ATOMIC_DEC(&pQueue->EntryCnt);
- return Entry;
- } /* QQ_PopTail */
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static PQQ_ENTRY
- QQ_GetHead(
- PQQ_CONTAINER pQueue,
- unsigned int Idx)
- {
- if(Idx >= (unsigned int) MM_ATOMIC_READ(&pQueue->EntryCnt))
- {
- return (PQQ_ENTRY) 0;
- }
- if(pQueue->Head > Idx)
- {
- Idx = pQueue->Head - Idx;
- }
- else
- {
- Idx = pQueue->Size - (Idx - pQueue->Head);
- }
- Idx--;
- return pQueue->Array[Idx];
- }
- /******************************************************************************/
- /* Description: */
- /* */
- /* Return: */
- /******************************************************************************/
- __inline static PQQ_ENTRY
- QQ_GetTail(
- PQQ_CONTAINER pQueue,
- unsigned int Idx)
- {
- if(Idx >= (unsigned int) MM_ATOMIC_READ(&pQueue->EntryCnt))
- {
- return (PQQ_ENTRY) 0;
- }
- Idx += pQueue->Tail;
- if(Idx >= pQueue->Size)
- {
- Idx = Idx - pQueue->Size;
- }
- return pQueue->Array[Idx];
- }
- #endif /* QQ_USE_MACROS */
- #endif /* QUEUE_H */
|