Com: Allow runtime bypass of freeListLib
By environment or iocsh variable.
This commit is contained in:
@@ -29,6 +29,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
LIBCOM_API extern int freeListBypass;
|
||||
|
||||
LIBCOM_API void epicsStdCall freeListInitPvt(void **ppvt, int size, int malloc);
|
||||
LIBCOM_API void * epicsStdCall freeListCalloc(void *pvt);
|
||||
LIBCOM_API void * epicsStdCall freeListMalloc(void *pvt);
|
||||
|
||||
@@ -26,6 +26,20 @@
|
||||
#include "epicsMutex.h"
|
||||
#include "freeList.h"
|
||||
#include "adjustment.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsString.h"
|
||||
#include "epicsAtomic.h"
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Bypass free list and directly call malloc() every time? */
|
||||
int freeListBypass
|
||||
#ifdef EPICS_FREELIST_DEBUG
|
||||
= 1;
|
||||
#else
|
||||
= 2; /* checks environment $EPICS_FREELIST_BYPASS */
|
||||
#endif
|
||||
|
||||
epicsExportAddress(int, freeListBypass);
|
||||
|
||||
typedef struct allocMem {
|
||||
struct allocMem *next;
|
||||
@@ -44,10 +58,25 @@ LIBCOM_API void epicsStdCall
|
||||
freeListInitPvt(void **ppvt,int size,int nmalloc)
|
||||
{
|
||||
FREELISTPVT *pfl;
|
||||
int bypass = epicsAtomicGetIntT(&freeListBypass);
|
||||
|
||||
if(bypass==2) {
|
||||
const char *str = getenv("EPICS_FREELIST_BYPASS");
|
||||
|
||||
if(str && epicsStrCaseCmp(str, "YES")==0) {
|
||||
bypass = 1;
|
||||
} else if(!str || str[0]=='\0' || epicsStrCaseCmp(str, "NO")==0) {
|
||||
bypass = 0;
|
||||
} else {
|
||||
errlogPrintf(ERL_WARNING " EPICS_FREELIST_BYPASS expected to be YES, NO, or empty. Not \"%s\"\n", str);
|
||||
}
|
||||
epicsAtomicSetIntT(&freeListBypass, bypass);
|
||||
}
|
||||
|
||||
pfl = callocMustSucceed(1,sizeof(FREELISTPVT), "freeListInitPvt");
|
||||
pfl->size = adjustToWorstCaseAlignment(size);
|
||||
pfl->nmalloc = nmalloc;
|
||||
if(!bypass)
|
||||
pfl->nmalloc = nmalloc; /* nmalloc==0 to bypass */
|
||||
pfl->head = NULL;
|
||||
pfl->mallochead = NULL;
|
||||
pfl->nBlocksAvailable = 0u;
|
||||
@@ -60,28 +89,26 @@ LIBCOM_API void epicsStdCall
|
||||
LIBCOM_API void * epicsStdCall freeListCalloc(void *pvt)
|
||||
{
|
||||
FREELISTPVT *pfl = pvt;
|
||||
# ifdef EPICS_FREELIST_DEBUG
|
||||
return callocMustSucceed(1,pfl->size,"freeList Debug Calloc");
|
||||
# else
|
||||
void *ptemp;
|
||||
|
||||
ptemp = freeListMalloc(pvt);
|
||||
if(ptemp) memset((char *)ptemp,0,pfl->size);
|
||||
if(!pfl->nmalloc)
|
||||
ptemp = calloc(1u, pfl->size);
|
||||
else if(!!(ptemp = freeListMalloc(pvt)))
|
||||
memset((char *)ptemp,0,pfl->size);
|
||||
return(ptemp);
|
||||
# endif
|
||||
}
|
||||
|
||||
LIBCOM_API void * epicsStdCall freeListMalloc(void *pvt)
|
||||
{
|
||||
FREELISTPVT *pfl = pvt;
|
||||
# ifdef EPICS_FREELIST_DEBUG
|
||||
return callocMustSucceed(1,pfl->size,"freeList Debug Malloc");
|
||||
# else
|
||||
void *ptemp;
|
||||
void **ppnext;
|
||||
allocMem *pallocmem;
|
||||
int i;
|
||||
|
||||
if(!pfl->nmalloc)
|
||||
return malloc(pfl->size);
|
||||
|
||||
epicsMutexMustLock(pfl->lock);
|
||||
ptemp = pfl->head;
|
||||
if(ptemp==0) {
|
||||
@@ -125,18 +152,18 @@ LIBCOM_API void * epicsStdCall freeListMalloc(void *pvt)
|
||||
VALGRIND_MEMPOOL_FREE(pfl, ptemp);
|
||||
VALGRIND_MEMPOOL_ALLOC(pfl, ptemp, pfl->size);
|
||||
return(ptemp);
|
||||
# endif
|
||||
}
|
||||
|
||||
LIBCOM_API void epicsStdCall freeListFree(void *pvt,void*pmem)
|
||||
{
|
||||
FREELISTPVT *pfl = pvt;
|
||||
# ifdef EPICS_FREELIST_DEBUG
|
||||
memset ( pmem, 0xdd, pfl->size );
|
||||
free(pmem);
|
||||
# else
|
||||
void **ppnext;
|
||||
|
||||
if(!pfl->nmalloc) {
|
||||
free(pmem);
|
||||
return;
|
||||
}
|
||||
|
||||
VALGRIND_MEMPOOL_FREE(pvt, pmem);
|
||||
VALGRIND_MEMPOOL_ALLOC(pvt, pmem, sizeof(void*));
|
||||
|
||||
@@ -146,7 +173,6 @@ LIBCOM_API void epicsStdCall freeListFree(void *pvt,void*pmem)
|
||||
pfl->head = pmem;
|
||||
pfl->nBlocksAvailable++;
|
||||
epicsMutexUnlock(pfl->lock);
|
||||
# endif
|
||||
}
|
||||
|
||||
LIBCOM_API void epicsStdCall freeListCleanup(void *pvt)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "taskwd.h"
|
||||
#include "registry.h"
|
||||
#include "epicsGeneralTime.h"
|
||||
#include "freeList.h"
|
||||
#include "libComRegister.h"
|
||||
|
||||
/* Register the PWD environment variable when the cd IOC shell function is
|
||||
@@ -467,7 +468,11 @@ static void installLastResortEventProviderCallFunc(const iocshArgBuf *args)
|
||||
installLastResortEventProvider();
|
||||
}
|
||||
|
||||
static iocshVarDef asCheckClientIPDef[] = { { "asCheckClientIP", iocshArgInt, 0 }, { NULL, iocshArgInt, NULL } };
|
||||
static iocshVarDef comDefs[] = {
|
||||
{ "asCheckClientIP", iocshArgInt, 0 },
|
||||
{ "freeListBypass", iocshArgInt, 0 },
|
||||
{ NULL, iocshArgInt, NULL }
|
||||
};
|
||||
|
||||
void epicsStdCall libComRegister(void)
|
||||
{
|
||||
@@ -504,6 +509,7 @@ void epicsStdCall libComRegister(void)
|
||||
iocshRegister(&generalTimeReportFuncDef,generalTimeReportCallFunc);
|
||||
iocshRegister(&installLastResortEventProviderFuncDef, installLastResortEventProviderCallFunc);
|
||||
|
||||
asCheckClientIPDef[0].pval = &asCheckClientIP;
|
||||
iocshRegisterVariable(asCheckClientIPDef);
|
||||
comDefs[0].pval = &asCheckClientIP;
|
||||
comDefs[1].pval = &freeListBypass;
|
||||
iocshRegisterVariable(comDefs);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user