Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*==========================================================================
* * Copyright (C) 1995 - 1997 Microsoft Corporation. All Rights Reserved. * * File: fpm.c * Content: fixed size pool manager * * History: * Date By Reason * ====== == ====== * 12-18-97 aarono Original ***************************************************************************/
#include "windows.h"
#include "dpsp.h"
#include "fpm.h"
#ifdef SENDEX
BOOL FN_BOOL_DUMMY(void *pvItem) { return TRUE; }
VOID FN_VOID_DUMMY(void *pvItem) { return; }
void * FPM_Get(LPFPOOL this) { void * pvItem;
EnterCriticalSection(&this->cs); if(!this->pPool){ LeaveCriticalSection(&this->cs); pvItem = GlobalAlloc(GPTR, this->cbItemSize);
if((pvItem) && !(*this->fnBlockInitAlloc)(pvItem) ){ GlobalFree(pvItem); pvItem=NULL; }
EnterCriticalSection(&this->cs);
if(pvItem){ this->nAllocated++; } } else { pvItem=this->pPool; this->pPool=*((void **)pvItem); }
if(pvItem){ (*this->fnBlockInit)(pvItem); this->nInUse++; if(this->nInUse > this->nMaxInUse){ this->nMaxInUse = this->nInUse; } }
LeaveCriticalSection(&this->cs);
return pvItem; }
#ifdef DEBUG
void DebugCheckList(void *pvList, void *pvItem) { void *pvWalker; DWORD n=0; pvWalker=pvList;
while(pvWalker){ if(pvWalker==pvItem){ DPF(0,"ERROR: Found Item %x in List %x, item # %d\n",pvList,pvItem,n); DEBUG_BREAK(); } n++; pvWalker=*((void **)pvWalker); } } #else
#define DebugCheckList()
#endif
void FPM_Release(LPFPOOL this, void *pvItem) { EnterCriticalSection(&this->cs); DebugCheckList(this->pPool, pvItem); //BUGBUG: debug only.
this->nInUse--; *((void**)pvItem)=this->pPool; this->pPool=pvItem; LeaveCriticalSection(&this->cs); }
void FPM_Scale(LPFPOOL this) { void * pvItem;
if(!InterlockedExchange(&this->bInScale,1)){
EnterCriticalSection(&this->cs);
while((this->nAllocated > this->nMaxInUse) && this->pPool){ pvItem = this->pPool; this->pPool=*((void **)pvItem); LeaveCriticalSection(&this->cs); (*this->fnBlockFini)(pvItem); GlobalFree(pvItem); EnterCriticalSection(&this->cs); this->nAllocated--; } this->nMaxInUse=this->nInUse;
LeaveCriticalSection(&this->cs);
InterlockedExchange(&this->bInScale,0); } }
VOID FPM_Fini(LPFPOOL this, int bFORCE) { void *pvItem;
while(this->pPool){ pvItem = this->pPool; this->pPool=*((void **)pvItem); (*this->fnBlockFini)(pvItem); GlobalFree(pvItem); this->nAllocated--; } if(this->nAllocated){ DPF(0,"WSOCK: Exiting with unfreed FPM pool items\n"); } DeleteCriticalSection(&this->cs); GlobalFree(this); }
LPFPOOL FPM_Init( unsigned int size, FN_BLOCKINITALLOC fnBlockInitAlloc, FN_BLOCKINIT fnBlockInit, FN_BLOCKFINI fnBlockFini) { LPFPOOL pPool; if(!(pPool=(LPFPOOL)GlobalAlloc(GPTR,sizeof(FPOOL)))) { return NULL; }
InitializeCriticalSection(&pPool->cs); // by zero init.
//pPool.pPool = NULL;
//pPool.nAllocated = 0;
//pPool.nInUse = 0;
//pPool.nMaxInUse = 0;
//pPool.bInScale = FALSE;
if(fnBlockInitAlloc){ pPool->fnBlockInitAlloc = fnBlockInitAlloc; } else { pPool->fnBlockInitAlloc = FN_BOOL_DUMMY; } if(fnBlockInit){ pPool->fnBlockInit = fnBlockInit; } else { pPool->fnBlockInit = FN_VOID_DUMMY; } if(fnBlockFini){ pPool->fnBlockFini = fnBlockFini; } else { pPool->fnBlockFini = FN_VOID_DUMMY; }
pPool->Get = FPM_Get; pPool->Release= FPM_Release; pPool->Scale = FPM_Scale; pPool->Fini = FPM_Fini;
pPool->cbItemSize = size; return pPool; }
#endif
|