Files
pcas/src/libCom/freeList/freeListLib.c
2015-08-18 15:51:38 -04:00

158 lines
4.0 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE Versions 3.13.7
* and higher are distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* $Revision-Id$ */
/* Author: Marty Kraimer Date: 04-19-94 */
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#define epicsExportSharedSymbols
#include "cantProceed.h"
#include "epicsMutex.h"
#include "freeList.h"
#include "adjustment.h"
typedef struct allocMem {
struct allocMem *next;
void *memory;
}allocMem;
typedef struct {
int size;
int nmalloc;
void *head;
allocMem *mallochead;
size_t nBlocksAvailable;
epicsMutexId lock;
}FREELISTPVT;
epicsShareFunc void epicsShareAPI
freeListInitPvt(void **ppvt,int size,int nmalloc)
{
FREELISTPVT *pfl;
pfl = callocMustSucceed(1,sizeof(FREELISTPVT), "freeListInitPvt");
pfl->size = adjustToWorstCaseAlignment(size);
pfl->nmalloc = nmalloc;
pfl->head = NULL;
pfl->mallochead = NULL;
pfl->nBlocksAvailable = 0u;
pfl->lock = epicsMutexMustCreate();
*ppvt = (void *)pfl;
return;
}
epicsShareFunc void * epicsShareAPI 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);
return(ptemp);
# endif
}
epicsShareFunc void * epicsShareAPI 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;
epicsMutexMustLock(pfl->lock);
ptemp = pfl->head;
if(ptemp==0) {
ptemp = (void *)malloc(pfl->nmalloc*pfl->size);
if(ptemp==0) {
epicsMutexUnlock(pfl->lock);
return(0);
}
pallocmem = (allocMem *)calloc(1,sizeof(allocMem));
if(pallocmem==0) {
epicsMutexUnlock(pfl->lock);
free(ptemp);
return(0);
}
pallocmem->memory = ptemp;
if(pfl->mallochead)
pallocmem->next = pfl->mallochead;
pfl->mallochead = pallocmem;
for(i=0; i<pfl->nmalloc; i++) {
ppnext = ptemp;
*ppnext = pfl->head;
pfl->head = ptemp;
ptemp = ((char *)ptemp) + pfl->size;
}
ptemp = pfl->head;
pfl->nBlocksAvailable += pfl->nmalloc;
}
ppnext = pfl->head;
pfl->head = *ppnext;
pfl->nBlocksAvailable--;
epicsMutexUnlock(pfl->lock);
return(ptemp);
# endif
}
epicsShareFunc void epicsShareAPI freeListFree(void *pvt,void*pmem)
{
FREELISTPVT *pfl = pvt;
# ifdef EPICS_FREELIST_DEBUG
memset ( pmem, 0xdd, pfl->size );
free(pmem);
# else
void **ppnext;
epicsMutexMustLock(pfl->lock);
ppnext = pmem;
*ppnext = pfl->head;
pfl->head = pmem;
pfl->nBlocksAvailable++;
epicsMutexUnlock(pfl->lock);
# endif
}
epicsShareFunc void epicsShareAPI freeListCleanup(void *pvt)
{
FREELISTPVT *pfl = pvt;
allocMem *phead;
allocMem *pnext;
phead = pfl->mallochead;
while(phead) {
pnext = phead->next;
free(phead->memory);
free(phead);
phead = pnext;
}
epicsMutexDestroy(pfl->lock);
free(pvt);
}
epicsShareFunc size_t epicsShareAPI freeListItemsAvail(void *pvt)
{
FREELISTPVT *pfl = pvt;
size_t nBlocksAvailable;
epicsMutexMustLock(pfl->lock);
nBlocksAvailable = pfl->nBlocksAvailable;
epicsMutexUnlock(pfl->lock);
return nBlocksAvailable;
}