📄 bcm570x_queue.h
字号:
/******************************************************************************//* *//* Broadcom BCM5700 Linux Network Driver, Copyright (c) 2000 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#ifndef EMBEDDED#define EMBEDDED 1#endif/******************************************************************************//* Queue definitions. *//******************************************************************************//* Entry for queueing. */typedef void *PQQ_ENTRY;/* Linux Atomic Ops support */typedef struct { int counter; } atomic_t;/* * This combination of `inline' and `extern' has almost the effect of a * macro. The way to use it is to put a function definition in a header * file with these keywords, and put another copy of the definition * (lacking `inline' and `extern') in a library file. The definition in * the header file will cause most calls to the function to be inlined. * If any uses of the function remain, they will refer to the single copy * in the library. */extern __inline voidatomic_set(atomic_t* entry, int val){ entry->counter = val;}extern __inline intatomic_read(atomic_t* entry){ return entry->counter;}extern __inline voidatomic_inc(atomic_t* entry){ if(entry) entry->counter++;}extern __inline voidatomic_dec(atomic_t* entry){ if(entry) entry->counter--;}extern __inline voidatomic_sub(int a, atomic_t* entry){ if(entry) entry->counter -= a;}extern __inline voidatomic_add(int a, atomic_t* entry){ if(entry) entry->counter += a;}/* Queue header -- base type. */typedef struct { unsigned int Head; unsigned int Tail; unsigned int Size; 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: *//******************************************************************************/extern __inline voidQQ_InitQueue(PQQ_CONTAINER pQueue,unsigned int QueueSize) { pQueue->Head = 0; pQueue->Tail = 0; pQueue->Size = QueueSize+1; atomic_set(&pQueue->EntryCnt, 0);} /* QQ_InitQueue *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/extern __inline charQQ_Full(PQQ_CONTAINER pQueue) { unsigned int NewHead; NewHead = (pQueue->Head + 1) % pQueue->Size; return(NewHead == pQueue->Tail);} /* QQ_Full *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/extern __inline charQQ_Empty(PQQ_CONTAINER pQueue) { return(pQueue->Head == pQueue->Tail);} /* QQ_Empty *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/extern __inline unsigned intQQ_GetSize(PQQ_CONTAINER pQueue) { return pQueue->Size;} /* QQ_GetSize *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/extern __inline unsigned intQQ_GetEntryCnt(PQQ_CONTAINER pQueue) { return atomic_read(&pQueue->EntryCnt);} /* QQ_GetEntryCnt *//******************************************************************************//* Description: *//* *//* Return: *//* TRUE entry was added successfully. *//* FALSE queue is full. *//******************************************************************************/extern __inline charQQ_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; wmb(); pQueue->Head = Head; atomic_inc(&pQueue->EntryCnt); return -1;} /* QQ_PushHead *//******************************************************************************//* Description: *//* *//* Return: *//* TRUE entry was added successfully. *//* FALSE queue is full. *//******************************************************************************/extern __inline charQQ_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; wmb(); pQueue->Tail = Tail; atomic_inc(&pQueue->EntryCnt); return -1;} /* QQ_PushTail *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/extern __inline PQQ_ENTRYQQ_PopHead(PQQ_CONTAINER pQueue) { unsigned int Head; PQQ_ENTRY Entry; Head = pQueue->Head;#if !defined(QQ_NO_UNDERFLOW_CHECK) if(Head == pQueue->Tail) { return (PQQ_ENTRY) 0; } /* if */#endif /* QQ_NO_UNDERFLOW_CHECK */ if(Head == 0) { Head = pQueue->Size; } /* if */ Head--; Entry = pQueue->Array[Head];#ifdef EMBEDDED membar();#else mb();#endif pQueue->Head = Head; atomic_dec(&pQueue->EntryCnt); return Entry;} /* QQ_PopHead *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/extern __inline PQQ_ENTRYQQ_PopTail(PQQ_CONTAINER pQueue) { unsigned int Tail; PQQ_ENTRY Entry; Tail = pQueue->Tail;#if !defined(QQ_NO_UNDERFLOW_CHECK) if(Tail == pQueue->Head) { return (PQQ_ENTRY) 0; } /* if */#endif /* QQ_NO_UNDERFLOW_CHECK */ Entry = pQueue->Array[Tail];#ifdef EMBEDDED membar();#else mb();#endif pQueue->Tail = (Tail + 1) % pQueue->Size; atomic_dec(&pQueue->EntryCnt); return Entry;} /* QQ_PopTail *//******************************************************************************//* Description: *//* *//* Return: *//******************************************************************************/extern __inline PQQ_ENTRYQQ_GetHead( PQQ_CONTAINER pQueue, unsigned int Idx){ if(Idx >= 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: *//******************************************************************************/extern __inline PQQ_ENTRYQQ_GetTail( PQQ_CONTAINER pQueue, unsigned int Idx){ if(Idx >= 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -