cas: simplify buffer alloc

eliminate casBufferFactory.
move small buffer free list into clientBufMemoryManager
This commit is contained in:
Michael Davidsaver
2017-03-18 16:17:19 -04:00
parent 2096c60652
commit 1e7c80c909
4 changed files with 36 additions and 136 deletions

View File

@@ -53,7 +53,6 @@ LIBSRCS += outBuf.cc
LIBSRCS += casCtx.cc
LIBSRCS += casEventMask.cc
LIBSRCS += ioBlocked.cc
LIBSRCS += casBufferFactory.cc
LIBSRCS += pvExistReturn.cc
LIBSRCS += pvAttachReturn.cc
LIBSRCS += caNetAddr.cc

View File

@@ -1,104 +0,0 @@
/*************************************************************************\
* 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.
\*************************************************************************/
/*
* Author Jeffrey O. Hill
* johill@lanl.gov
* 505 665 1831
*/
#include <new>
#include "envDefs.h"
#include "freeList.h"
#include "errlog.h"
#define epicsExportSharedSymbols
#include "clientBufMemoryManager.h"
#include "caProto.h"
casBufferFactory::casBufferFactory () :
smallBufFreeList ( 0 ), largeBufFreeList ( 0 ), largeBufferSizePriv ( 0u )
{
long maxBytesAsALong;
long status = envGetLongConfigParam ( & EPICS_CA_MAX_ARRAY_BYTES, & maxBytesAsALong );
if ( status || maxBytesAsALong < 0 ) {
errlogPrintf ( "cas: EPICS_CA_MAX_ARRAY_BYTES was not a positive integer\n" );
this->largeBufferSizePriv = MAX_TCP;
}
else {
/* allow room for the protocol header so that they get the array size they requested */
static const unsigned headerSize = sizeof ( caHdr ) + 2 * sizeof ( ca_uint32_t );
ca_uint32_t maxBytes = ( unsigned ) maxBytesAsALong;
if ( maxBytes < 0xffffffff - headerSize ) {
maxBytes += headerSize;
}
else {
maxBytes = 0xffffffff;
}
if ( maxBytes < MAX_TCP ) {
errlogPrintf ( "cas: EPICS_CA_MAX_ARRAY_BYTES was rounded up to %u\n", MAX_TCP );
this->largeBufferSizePriv = MAX_TCP;
}
else {
this->largeBufferSizePriv = maxBytes;
}
}
freeListInitPvt ( & this->smallBufFreeList, MAX_MSG_SIZE, 8 );
freeListInitPvt ( & this->largeBufFreeList, this->largeBufferSizePriv, 1 );
}
casBufferFactory::~casBufferFactory ()
{
freeListCleanup ( this->smallBufFreeList );
freeListCleanup ( this->largeBufFreeList );
}
unsigned casBufferFactory::smallBufferSize () const
{
return MAX_MSG_SIZE;
}
char * casBufferFactory::newSmallBuffer ()
{
void * pBuf = freeListCalloc ( this->smallBufFreeList );
if ( ! pBuf ) {
throw std::bad_alloc();
}
return static_cast < char * > ( pBuf );
}
void casBufferFactory::destroySmallBuffer ( char * pBuf )
{
if ( pBuf ) {
freeListFree ( this->smallBufFreeList, pBuf );
}
}
unsigned casBufferFactory::largeBufferSize () const
{
return this->largeBufferSizePriv;
}
char * casBufferFactory::newLargeBuffer ()
{
void * pBuf = freeListCalloc ( this->largeBufFreeList );
if ( ! pBuf ) {
throw std::bad_alloc();
}
return static_cast < char * > ( pBuf );
}
void casBufferFactory::destroyLargeBuffer ( char * pBuf )
{
if ( pBuf ) {
freeListFree ( this->largeBufFreeList, pBuf );
}
}

View File

@@ -13,37 +13,54 @@
* 505 665 1831
*/
#include <new>
#include <stdlib.h>
#include "epicsAssert.h"
#include "freeList.h"
#define epicsExportSharedSymbols
#include "clientBufMemoryManager.h"
#include "caProto.h"
clientBufMemoryManager::clientBufMemoryManager()
:smallBufFreeList ( 0 )
{
freeListInitPvt ( & this->smallBufFreeList, MAX_MSG_SIZE, 8 );
}
clientBufMemoryManager::~clientBufMemoryManager()
{
freeListCleanup ( this->smallBufFreeList );
}
casBufferParm clientBufMemoryManager::allocate ( bufSizeT newMinSize )
{
casBufferParm parm;
if ( newMinSize <= bufferFactory.smallBufferSize () ) {
parm.pBuf = bufferFactory.newSmallBuffer ();
parm.bufSize = bufferFactory.smallBufferSize ();
}
else if ( newMinSize <= bufferFactory.largeBufferSize () ) {
parm.pBuf = bufferFactory.newLargeBuffer ();
parm.bufSize = bufferFactory.largeBufferSize ();
if ( newMinSize <= MAX_MSG_SIZE ) {
parm.pBuf = (char*)freeListMalloc(this->smallBufFreeList);
parm.bufSize = MAX_MSG_SIZE;
}
else {
parm.pBuf = static_cast < char * > ( ::operator new ( newMinSize ) );
// round size up to multiple of 4K
newMinSize = ((newMinSize-1)|0xfff)+1;
parm.pBuf = (char*)malloc(newMinSize);
parm.bufSize = newMinSize;
}
if(!parm.pBuf)
throw std::bad_alloc();
return parm;
}
void clientBufMemoryManager::release ( char * pBuf, bufSizeT bufSize )
{
if ( bufSize == bufferFactory.smallBufferSize () ) {
bufferFactory.destroySmallBuffer ( pBuf );
}
else if ( bufSize == bufferFactory.largeBufferSize () ) {
bufferFactory.destroyLargeBuffer ( pBuf );
assert(pBuf);
if (bufSize <= MAX_MSG_SIZE) {
freeListFree(this->smallBufFreeList, pBuf);
}
else {
::operator delete ( pBuf );
free(pBuf);
}
}

View File

@@ -16,22 +16,6 @@
typedef unsigned bufSizeT;
static const unsigned bufSizeT_MAX = UINT_MAX;
class casBufferFactory {
public:
casBufferFactory ();
~casBufferFactory ();
unsigned smallBufferSize () const;
char * newSmallBuffer ();
void destroySmallBuffer ( char * pBuf );
unsigned largeBufferSize () const;
char * newLargeBuffer ();
void destroyLargeBuffer ( char * pBuf );
private:
void * smallBufFreeList;
void * largeBufFreeList;
unsigned largeBufferSizePriv;
};
struct casBufferParm {
char * pBuf;
bufSizeT bufSize;
@@ -39,11 +23,15 @@ struct casBufferParm {
class clientBufMemoryManager {
public:
clientBufMemoryManager();
~clientBufMemoryManager();
//! @throws std::bad_alloc on failure
casBufferParm allocate ( bufSizeT newMinSize );
void release ( char * pBuf, bufSizeT bufSize );
private:
casBufferFactory bufferFactory;
void * smallBufFreeList;
};
#endif // clientBufMemoryManagerh