From 3009f88f6486e7e63445b03664b4638859cd8f3e Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 13 Mar 2017 19:22:56 -0400 Subject: [PATCH] rsrv: support larger than max. array bytes --- src/ioc/rsrv/caservertask.c | 109 ++++++++++++++++++++++++++---------- src/ioc/rsrv/server.h | 2 +- 2 files changed, 79 insertions(+), 32 deletions(-) diff --git a/src/ioc/rsrv/caservertask.c b/src/ioc/rsrv/caservertask.c index a18abafe2..a138fbba9 100644 --- a/src/ioc/rsrv/caservertask.c +++ b/src/ioc/rsrv/caservertask.c @@ -1060,6 +1060,9 @@ void destroy_client ( struct client *client ) else if ( client->send.type == mbtLargeTCP ) { freeListFree ( rsrvLargeBufFreeListTCP, client->send.buf ); } + else if (client->send.type == mbtHugeTCP ) { + free ( client->send.buf ); + } else { errlogPrintf ( "CAS: Corrupt send buffer free list type code=%u during client cleanup?\n", client->send.type ); @@ -1072,6 +1075,9 @@ void destroy_client ( struct client *client ) else if ( client->recv.type == mbtLargeTCP ) { freeListFree ( rsrvLargeBufFreeListTCP, client->recv.buf ); } + else if (client->recv.type == mbtHugeTCP ) { + free ( client->recv.buf ); + } else { errlogPrintf ( "CAS: Corrupt recv buffer free list type code=%u during client cleanup?\n", client->send.type ); @@ -1301,43 +1307,84 @@ void casAttachThreadToClient ( struct client *pClient ) taskwdInsert ( pClient->tid, NULL, NULL ); } +static +void casExpandBuffer ( struct message_buffer *buf, ca_uint32_t size, int sendbuf ) +{ + char *newbuf = NULL; + unsigned newsize; + enum messageBufferType newtype; + + assert (size > MAX_TCP); + + if ( size <= buf->maxstk || buf->type == mbtUDP ) return; + + /* try to alloc new buffer */ + if (size <= MAX_TCP) { + return; /* shouldn't happen */ + } else if (size <= rsrvSizeofLargeBufTCP) { + newbuf = freeListCalloc ( rsrvLargeBufFreeListTCP ); + newsize = rsrvSizeofLargeBufTCP; + newtype = mbtLargeTCP; + } +#ifndef NO_HUGE + else { + size = ((size-1)|0xfff)+1; + + if (buf->type==mbtHugeTCP) + newbuf = realloc (buf->buf, size); + else + newbuf = malloc (size); + newtype = mbtHugeTCP; + newsize = size; + } +#endif + + if (newbuf) { + /* copy existing buffer */ + if (sendbuf) { + /* send buffer uses [0, stk) */ + if (buf->type==mbtHugeTCP) { + /* realloc already copied */ + } else { + memcpy ( newbuf, buf->buf, buf->stk ); + } + } else { + /* recv buffer uses [stk, cnt) */ + unsigned used; + assert ( buf->cnt >= buf->stk ); + used = buf->cnt - buf->stk; + + /* buf->buf may be the same as newbuf if realloc() used */ + memmove ( newbuf, &buf->buf[buf->stk], used ); + + buf->cnt = used; + buf->stk = 0; + + } + + /* free existing buffer */ + if(buf->type==mbtSmallTCP) { + freeListFree ( rsrvSmallBufFreeListTCP, buf->buf ); + } else if(buf->type==mbtLargeTCP) { + freeListFree ( rsrvLargeBufFreeListTCP, buf->buf ); + } else { + /* realloc() already free()'d if necessary */ + } + + buf->buf = newbuf; + buf->type = newtype; + buf->maxstk = newsize; + } +} + void casExpandSendBuffer ( struct client *pClient, ca_uint32_t size ) { - if ( pClient->send.type == mbtSmallTCP && rsrvSizeofLargeBufTCP > MAX_TCP - && size <= rsrvSizeofLargeBufTCP ) { - int spaceAvailOnFreeList = freeListItemsAvail ( rsrvLargeBufFreeListTCP ) > 0; - if ( osiSufficentSpaceInPool(rsrvSizeofLargeBufTCP) || 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; - } - } - } + casExpandBuffer (&pClient->send, size, 1); } void casExpandRecvBuffer ( struct client *pClient, ca_uint32_t size ) { - if ( pClient->recv.type == mbtSmallTCP && rsrvSizeofLargeBufTCP > MAX_TCP - && size <= rsrvSizeofLargeBufTCP) { - int spaceAvailOnFreeList = freeListItemsAvail ( rsrvLargeBufFreeListTCP ) > 0; - if ( osiSufficentSpaceInPool(rsrvSizeofLargeBufTCP) || 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; - } - } - } + casExpandBuffer (&pClient->recv, size, 0); } /* diff --git a/src/ioc/rsrv/server.h b/src/ioc/rsrv/server.h index d2a1cf3f4..86407a8c5 100644 --- a/src/ioc/rsrv/server.h +++ b/src/ioc/rsrv/server.h @@ -60,7 +60,7 @@ typedef struct caHdrLargeArray { * Eight-byte alignment is required by the Sparc 5 and other RISC * processors. */ -enum messageBufferType { mbtUDP, mbtSmallTCP, mbtLargeTCP }; +enum messageBufferType { mbtUDP, mbtSmallTCP, mbtLargeTCP, mbtHugeTCP }; struct message_buffer { char *buf; unsigned stk;