From b231b3a365ddda463abb2a0428716a1748642cde Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Tue, 26 Feb 2002 19:47:35 +0000 Subject: [PATCH] improved memory management --- src/rsrv/camessage.c | 20 ++++++++++---- src/rsrv/caservertask.c | 60 ++++++++++++++++++++++++++--------------- 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/rsrv/camessage.c b/src/rsrv/camessage.c index 50dd5e092..9797a7b36 100644 --- a/src/rsrv/camessage.c +++ b/src/rsrv/camessage.c @@ -1614,6 +1614,7 @@ LOCAL int write_notify_action ( caHdrLargeArray *mp, void *pPayload, LOCAL int event_add_action (caHdrLargeArray *mp, void *pPayload, struct client *client) { struct mon_info *pmi = (struct mon_info *) pPayload; + int spaceAvailOnFreeList; struct channel_in_use *pciu; struct event_ext *pevext; @@ -1623,7 +1624,17 @@ LOCAL int event_add_action (caHdrLargeArray *mp, void *pPayload, struct client * return RSRV_ERROR; } - pevext = (struct event_ext *) freeListCalloc (rsrvEventFreeList); + /* + * stop further use of server if memory becomes scarse + */ + spaceAvailOnFreeList = freeListItemsAvail ( rsrvEventFreeList ) > 0; + if ( casSufficentSpaceInPool || spaceAvailOnFreeList ) { + pevext = (struct event_ext *) freeListCalloc (rsrvEventFreeList); + } + else { + pevext = 0; + } + if (!pevext) { log_header ("no memory to add subscription", client, mp, pPayload, 0); @@ -1963,10 +1974,9 @@ LOCAL int search_reply ( caHdrLargeArray *mp, void *pPayload, struct client *cli /* * stop further use of server if memory becomes scarse */ - spaceAvailOnFreeList = freeListItemsAvail (rsrvClientFreeList) > 0 - && freeListItemsAvail (rsrvChanFreeList) > 0 - && freeListItemsAvail (rsrvEventFreeList) > 0; - if ( ! casSufficentSpaceInPool && ! spaceAvailOnFreeList ) { + spaceAvailOnFreeList = freeListItemsAvail ( rsrvChanFreeList ) > 0 + && freeListItemsAvail ( rsrvEventFreeList ) > 0; + if ( ! ( casSufficentSpaceInPool || spaceAvailOnFreeList ) ) { SEND_LOCK(client); send_err ( mp, ECA_ALLOCMEM, client, "Server memory exhausted" ); SEND_UNLOCK(client); diff --git a/src/rsrv/caservertask.c b/src/rsrv/caservertask.c index e7ce406aa..051ce2697 100644 --- a/src/rsrv/caservertask.c +++ b/src/rsrv/caservertask.c @@ -202,8 +202,6 @@ LOCAL int req_server (void) pClient = create_tcp_client ( clientSock ); if ( ! pClient ) { - errlogPrintf ( "CAS: unable to create new client because \"%s\"\n", - strerror ( errno ) ); epicsThreadSleep ( 15.0 ); continue; } @@ -461,7 +459,7 @@ void epicsShareAPI casr (unsigned level) freeListItemsAvail (rsrvEventFreeList)); printf( "%u small buffers (%u bytes ea), and %u jumbo buffers (%u bytes ea)\n", freeListItemsAvail ( rsrvSmallBufFreeListTCP ), MAX_TCP, - freeListItemsAvail (rsrvLargeBufFreeListTCP), rsrvSizeofLargeBufTCP ); + freeListItemsAvail ( rsrvLargeBufFreeListTCP ), rsrvSizeofLargeBufTCP ); if(pCaBucket){ printf( "The server's resource id conversion table:\n"); LOCK_CLIENTQ; @@ -631,10 +629,21 @@ void destroy_tcp_client ( struct client *client ) struct client * create_client ( SOCKET sock, int proto ) { struct client *client; - + int spaceAvailOnFreeList; + + /* + * stop further use of server if memory becomes scarse + */ + spaceAvailOnFreeList = freeListItemsAvail ( rsrvClientFreeList ) > 0 + && freeListItemsAvail ( rsrvSmallBufFreeListTCP ) > 0; + if ( ! ( casSufficentSpaceInPool || spaceAvailOnFreeList ) ) { + epicsPrintf ("CAS: no space in pool for a new client (below max block thresh)\n"); + return NULL; + } + client = freeListCalloc ( rsrvClientFreeList ); if ( ! client ) { - epicsPrintf ("CAS: no space in pool for a new client\n"); + epicsPrintf ("CAS: no space in pool for a new client (alloc failed)\n"); return NULL; } @@ -704,12 +713,17 @@ void casExpandSendBuffer ( struct client *pClient, ca_uint32_t size ) { if ( pClient->send.type == mbtSmallTCP && rsrvSizeofLargeBufTCP > MAX_TCP && size <= rsrvSizeofLargeBufTCP ) { - char *pNewBuf = ( char * ) freeListCalloc ( rsrvLargeBufFreeListTCP ); - memcpy ( pNewBuf, pClient->send.buf, pClient->send.stk ); - freeListFree ( rsrvSmallBufFreeListTCP, pClient->send.buf ); - pClient->send.buf = pNewBuf; - pClient->send.maxstk = rsrvSizeofLargeBufTCP; - pClient->send.type = mbtLargeTCP; + int spaceAvailOnFreeList = freeListItemsAvail ( rsrvLargeBufFreeListTCP ) > 0; + if ( casSufficentSpaceInPool || spaceAvailOnFreeList ) { + char *pNewBuf = ( char * ) freeListCalloc ( rsrvLargeBufFreeListTCP ); + if ( pNewBuf ) { + memcpy ( pNewBuf, pClient->send.buf, pClient->send.stk ); + freeListFree ( rsrvSmallBufFreeListTCP, pClient->send.buf ); + pClient->send.buf = pNewBuf; + pClient->send.maxstk = rsrvSizeofLargeBufTCP; + pClient->send.type = mbtLargeTCP; + } + } } } @@ -717,15 +731,20 @@ void casExpandRecvBuffer ( struct client *pClient, ca_uint32_t size ) { if ( pClient->recv.type == mbtSmallTCP && rsrvSizeofLargeBufTCP > MAX_TCP && size <= rsrvSizeofLargeBufTCP) { - char *pNewBuf = ( char * ) freeListCalloc ( rsrvLargeBufFreeListTCP ); - assert ( pClient->recv.cnt >= pClient->recv.stk ); - memcpy ( pNewBuf, &pClient->recv.buf[pClient->recv.stk], pClient->recv.cnt - pClient->recv.stk ); - freeListFree ( rsrvSmallBufFreeListTCP, pClient->recv.buf ); - pClient->recv.buf = pNewBuf; - pClient->recv.cnt = pClient->recv.cnt - pClient->recv.stk; - pClient->recv.stk = 0u; - pClient->recv.maxstk = rsrvSizeofLargeBufTCP; - pClient->recv.type = mbtLargeTCP; + int spaceAvailOnFreeList = freeListItemsAvail ( rsrvLargeBufFreeListTCP ) > 0; + if ( casSufficentSpaceInPool || spaceAvailOnFreeList ) { + char *pNewBuf = ( char * ) freeListCalloc ( rsrvLargeBufFreeListTCP ); + if ( pNewBuf ) { + assert ( pClient->recv.cnt >= pClient->recv.stk ); + memcpy ( pNewBuf, &pClient->recv.buf[pClient->recv.stk], pClient->recv.cnt - pClient->recv.stk ); + freeListFree ( rsrvSmallBufFreeListTCP, pClient->recv.buf ); + pClient->recv.buf = pNewBuf; + pClient->recv.cnt = pClient->recv.cnt - pClient->recv.stk; + pClient->recv.stk = 0u; + pClient->recv.maxstk = rsrvSizeofLargeBufTCP; + pClient->recv.type = mbtLargeTCP; + } + } } } @@ -742,7 +761,6 @@ struct client *create_tcp_client ( SOCKET sock ) client = create_client ( sock, IPPROTO_TCP ); if ( ! client ) { - errlogPrintf ("CAS: no space in pool for a new TCP client\n"); return NULL; }