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.
 
 
 
 
 
 

195 lines
3.5 KiB

/*==========================================================================
*
* 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