// Copyright (c) 1997-1999 Microsoft Corporation // // bpool.h // RAS L2TP WAN mini-port/call-manager driver // Buffer pool management header // // 01/07/97 Steve Cobb, adapted from Gurdeep's WANARP code. #ifndef _BPOOL_H_ #define _BPOOL_H_ //----------------------------------------------------------------------------- // Data structures //----------------------------------------------------------------------------- // Buffer pool control block. A buffer pool prevents fragmentation of the // non-paged memory pool by allocating the memory for a group of buffers in a // single contiguous block. At user's option, the buffer pool routines may // allocate a pool of NDIS_BUFFER buffer descriptors and associate each with // the memory buffers sliced from the contiguous block. This allows the // buffer to be reused while the virtual->physical memory mapping is performed // only once. All necessary pool growth and shrinkage is handled internally. // typedef struct _BUFFERPOOL { // Size in bytes of an individual buffer in the pool. // ULONG ulBufferSize; // The optimal number of buffers to allocate in each buffer block. // ULONG ulBuffersPerBlock; // Maximum number of individual buffers that may be allocated in the // entire pool or 0 for unlimited. // ULONG ulMaxBuffers; // Current number of individual buffers allocated in the entire pool. // ULONG ulCurBuffers; // Garbage collection occurs after this many calls to FreeBufferToPool. // ULONG ulFreesPerCollection; // Number of calls to FreeBufferToPool since a garbage collection. // ULONG ulFreesSinceCollection; // Indicates an NDIS_BUFFER is to be associated with each individual // buffer in the pool. // BOOLEAN fAssociateNdisBuffer; // Memory identification tag for allocated blocks. // ULONG ulTag; // Head of the double linked list of BUFFERBLOCKHEADs. Access to the list // is protected with 'lock' in this structure. // LIST_ENTRY listBlocks; // Head of the double linked list of free BUFFERHEADs. Each BUFFERHEAD in // the list is ready to go, i.e. it preceeds it's already allocated memory // buffer and, if appropriate, has an NDIS_BUFFER associated with it. // Access to the list is protected by 'lock' in this structure. // Interlocked push/pop is not used because (a) the list of blocks and the // list of buffers must lock each other and (b) double links are necessary // for garbage collection. // LIST_ENTRY listFreeBuffers; // This lock protects this structure and both the list of blocks and the // list of buffers. // NDIS_SPIN_LOCK lock; } BUFFERPOOL; // Header of a single block of buffers from a buffer pool. The BUFFERHEAD of // the first buffer immediately follows. // typedef struct _BUFFERBLOCKHEAD { // Link to the prev/next buffer block header in the buffer pool's list. // LIST_ENTRY linkBlocks; // NDIS's handle of the pool of NDIS_BUFFER descriptors associated with // this block, or NULL if none. (Note: With the current NT implementation // of NDIS_BUFFER as MDL this is always NULL). // NDIS_HANDLE hNdisPool; // Back pointer to the buffer pool. // BUFFERPOOL* pPool; // Number of individual buffers in this block. // ULONG ulBuffers; // Number of individual buffers in this block on the free list. // ULONG ulFreeBuffers; } BUFFERBLOCKHEAD; // Header of an individual buffer. The buffer memory itself immediately // follows. // typedef struct _BUFFERHEAD { // Links to prev/next buffer header in the buffer pool's free list. // LIST_ENTRY linkFreeBuffers; // Back link to owning buffer block header. // BUFFERBLOCKHEAD* pBlock; // NDIS buffer descriptor of this buffer. This is NULL unless the pool is // initialized with the 'fAssociateNdisBuffer' option. // NDIS_BUFFER* pNdisBuffer; } BUFFERHEAD; //----------------------------------------------------------------------------- // Interface prototypes and inline definitions //----------------------------------------------------------------------------- VOID InitBufferPool( OUT BUFFERPOOL* pPool, IN ULONG ulBufferSize, IN ULONG ulMaxBuffers, IN ULONG ulBuffersPerBlock, IN ULONG ulFreesPerCollection, IN BOOLEAN fAssociateNdisBuffer, IN ULONG ulTag ); BOOLEAN FreeBufferPool( IN BUFFERPOOL* pPool ); CHAR* GetBufferFromPool( IN BUFFERPOOL* pPool ); VOID FreeBufferToPool( IN BUFFERPOOL* pPool, IN CHAR* pBuffer, IN BOOLEAN fGarbageCollection ); NDIS_BUFFER* NdisBufferFromBuffer( IN CHAR* pBuffer ); ULONG BufferSizeFromBuffer( IN CHAR* pBuffer ); NDIS_BUFFER* PoolHandleForNdisCopyBufferFromBuffer( IN CHAR* pBuffer ); VOID CollectBufferPoolGarbage( BUFFERPOOL* pPool ); #endif // BPOOL_H_