fixed SPARC alignment with ca put notify
This commit is contained in:
@@ -51,6 +51,36 @@ LOCAL EVENTFUNC read_reply;
|
||||
#define logBadId(CLIENT, MP, PPL)\
|
||||
logBadIdWithFileAndLineno(CLIENT, MP, PPL, __FILE__, __LINE__)
|
||||
|
||||
/*
|
||||
* for tracking db put notifies
|
||||
*/
|
||||
typedef struct rsrv_put_notify {
|
||||
ELLNODE node;
|
||||
putNotify dbPutNotify;
|
||||
caHdrLargeArray msg;
|
||||
unsigned valueSize; /* size of block pointed to by dbPutNotify */
|
||||
char busy; /* put notify in progress */
|
||||
char onExtraLaborQueue;
|
||||
/*
|
||||
* Include a union of all scalar types
|
||||
* including fixed length strings so
|
||||
* that in many cases we can avoid
|
||||
* allocating another buffer and only
|
||||
* use an rsrv_put_notify from its
|
||||
* free list.
|
||||
*/
|
||||
union {
|
||||
dbr_string_t strval;
|
||||
dbr_short_t shrtval;
|
||||
dbr_short_t intval;
|
||||
dbr_float_t fltval;
|
||||
dbr_enum_t enmval;
|
||||
dbr_char_t charval;
|
||||
dbr_long_t longval;
|
||||
dbr_double_t doubleval;
|
||||
} dbrScalarValue;
|
||||
} RSRVPUTNOTIFY;
|
||||
|
||||
/*
|
||||
* casCalloc()
|
||||
*
|
||||
@@ -1478,6 +1508,116 @@ LOCAL void putNotifyErrorReply ( struct client *client, caHdrLargeArray *mp, int
|
||||
SEND_UNLOCK ( client );
|
||||
}
|
||||
|
||||
void initializePutNotifyFreeList ()
|
||||
{
|
||||
if ( ! rsrvPutNotifyFreeList ) {
|
||||
freeListInitPvt ( &rsrvPutNotifyFreeList,
|
||||
sizeof(struct rsrv_put_notify), 512 );
|
||||
assert ( rsrvPutNotifyFreeList );
|
||||
}
|
||||
}
|
||||
|
||||
static struct rsrv_put_notify *
|
||||
rsrvAllocPutNotify ( struct channel_in_use * pciu )
|
||||
{
|
||||
struct rsrv_put_notify *pNotify;
|
||||
|
||||
if ( rsrvPutNotifyFreeList ) {
|
||||
pNotify = (RSRVPUTNOTIFY *)
|
||||
freeListCalloc ( rsrvPutNotifyFreeList );
|
||||
if ( pNotify ) {
|
||||
pNotify->dbPutNotify.pbuffer =
|
||||
&pNotify->dbrScalarValue;
|
||||
pNotify->valueSize =
|
||||
sizeof (pNotify->dbrScalarValue);
|
||||
pNotify->dbPutNotify.usrPvt = pciu;
|
||||
pNotify->dbPutNotify.paddr = &pciu->addr;
|
||||
pNotify->dbPutNotify.userCallback =
|
||||
write_notify_call_back;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pNotify = NULL;
|
||||
}
|
||||
return pNotify;
|
||||
}
|
||||
|
||||
static int rsrvExpandPutNotify (
|
||||
struct rsrv_put_notify * pNotify, unsigned sizeNeeded )
|
||||
{
|
||||
int booleanStatus;
|
||||
|
||||
if ( sizeNeeded > pNotify->valueSize ) {
|
||||
/*
|
||||
* try to use the union embeded in the free list
|
||||
* item, but allocate a random sized block if they
|
||||
* writing a vector.
|
||||
*/
|
||||
if ( pNotify->valueSize >
|
||||
sizeof (pNotify->dbrScalarValue) ) {
|
||||
free ( pNotify->dbPutNotify.pbuffer );
|
||||
}
|
||||
pNotify->dbPutNotify.pbuffer = casCalloc(1,sizeNeeded);
|
||||
if ( pNotify->dbPutNotify.pbuffer ) {
|
||||
pNotify->valueSize = sizeNeeded;
|
||||
booleanStatus = TRUE;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* revert back to the embedded union
|
||||
*/
|
||||
pNotify->dbPutNotify.pbuffer =
|
||||
&pNotify->dbrScalarValue;
|
||||
pNotify->valueSize =
|
||||
sizeof (pNotify->dbrScalarValue);
|
||||
booleanStatus = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
booleanStatus = TRUE;
|
||||
}
|
||||
|
||||
return booleanStatus;
|
||||
}
|
||||
|
||||
unsigned rsrvSizeOfPutNotify ( struct rsrv_put_notify *pNotify )
|
||||
{
|
||||
unsigned size = sizeof ( *pNotify );
|
||||
if ( pNotify ) {
|
||||
if ( pNotify->valueSize >
|
||||
sizeof ( pNotify->dbrScalarValue ) ) {
|
||||
size += pNotify->valueSize;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
void rsrvFreePutNotify ( client *pClient,
|
||||
struct rsrv_put_notify *pNotify )
|
||||
{
|
||||
if ( pNotify ) {
|
||||
/*
|
||||
* if the put notify is outstanding then cancel it
|
||||
*/
|
||||
if ( pNotify->busy ) {
|
||||
dbNotifyCancel ( &pNotify->dbPutNotify );
|
||||
}
|
||||
|
||||
epicsMutexMustLock ( pClient->putNotifyLock );
|
||||
if ( pNotify->onExtraLaborQueue ) {
|
||||
ellDelete ( &pClient->putNotifyQue,
|
||||
&pNotify->node );
|
||||
}
|
||||
epicsMutexUnlock ( pClient->putNotifyLock );
|
||||
|
||||
if ( pNotify->valueSize >
|
||||
sizeof(pNotify->dbrScalarValue) ) {
|
||||
free ( pNotify->dbPutNotify.pbuffer );
|
||||
}
|
||||
freeListFree ( rsrvPutNotifyFreeList, pNotify );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* write_notify_action()
|
||||
*/
|
||||
@@ -1507,7 +1647,7 @@ LOCAL int write_notify_action ( caHdrLargeArray *mp, void *pPayload,
|
||||
|
||||
size = dbr_size_n (mp->m_dataType, mp->m_count);
|
||||
|
||||
if (pciu->pPutNotify) {
|
||||
if ( pciu->pPutNotify ) {
|
||||
|
||||
/*
|
||||
* serialize concurrent put notifies
|
||||
@@ -1523,35 +1663,26 @@ LOCAL int write_notify_action ( caHdrLargeArray *mp, void *pPayload,
|
||||
return RSRV_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if not busy then free the current
|
||||
* block if it is to small
|
||||
*/
|
||||
if(pciu->pPutNotify->valueSize<size){
|
||||
free(pciu->pPutNotify);
|
||||
pciu->pPutNotify = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* send error and go to next request
|
||||
* if there isnt enough memory left
|
||||
*/
|
||||
if(!pciu->pPutNotify){
|
||||
pciu->pPutNotify = (RSRVPUTNOTIFY *)
|
||||
casCalloc(1, sizeof(*pciu->pPutNotify)+size);
|
||||
if(!pciu->pPutNotify){
|
||||
else {
|
||||
pciu->pPutNotify = rsrvAllocPutNotify ( pciu );
|
||||
if ( ! pciu->pPutNotify ) {
|
||||
/*
|
||||
* send error and go to next request
|
||||
* if there isnt enough memory left
|
||||
*/
|
||||
log_header ( "no memory to initiate put notify",
|
||||
client, mp, pPayload, 0 );
|
||||
putNotifyErrorReply (client, mp, ECA_ALLOCMEM);
|
||||
return RSRV_ERROR;
|
||||
}
|
||||
pciu->pPutNotify->valueSize = size;
|
||||
pciu->pPutNotify->dbPutNotify.pbuffer = (pciu->pPutNotify+1);
|
||||
pciu->pPutNotify->dbPutNotify.usrPvt = pciu;
|
||||
pciu->pPutNotify->dbPutNotify.paddr = &pciu->addr;
|
||||
pciu->pPutNotify->dbPutNotify.userCallback = write_notify_call_back;
|
||||
}
|
||||
|
||||
if ( ! rsrvExpandPutNotify ( pciu->pPutNotify, size ) ) {
|
||||
log_header ( "no memory to initiate vector put notify",
|
||||
client, mp, pPayload, 0 );
|
||||
putNotifyErrorReply ( client, mp, ECA_ALLOCMEM );
|
||||
return RSRV_ERROR;
|
||||
}
|
||||
|
||||
pciu->pPutNotify->busy = TRUE;
|
||||
@@ -1690,7 +1821,8 @@ LOCAL int event_add_action (caHdrLargeArray *mp, void *pPayload, struct client *
|
||||
/*
|
||||
* clear_channel_reply()
|
||||
*/
|
||||
LOCAL int clear_channel_reply ( caHdrLargeArray *mp, void *pPayload, struct client *client )
|
||||
LOCAL int clear_channel_reply ( caHdrLargeArray *mp,
|
||||
void *pPayload, struct client *client )
|
||||
{
|
||||
struct event_ext *pevext;
|
||||
struct channel_in_use *pciu;
|
||||
@@ -1707,19 +1839,7 @@ LOCAL int clear_channel_reply ( caHdrLargeArray *mp, void *pPayload, struct clie
|
||||
return RSRV_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* if a put notify is outstanding then cancel it
|
||||
*/
|
||||
if(pciu->pPutNotify){
|
||||
if(pciu->pPutNotify->busy){
|
||||
dbNotifyCancel ( &pciu->pPutNotify->dbPutNotify );
|
||||
}
|
||||
epicsMutexMustLock ( client->putNotifyLock );
|
||||
if ( pciu->pPutNotify->onExtraLaborQueue ) {
|
||||
ellDelete ( &client->putNotifyQue, &pciu->pPutNotify->node );
|
||||
}
|
||||
epicsMutexUnlock ( client->putNotifyLock );
|
||||
}
|
||||
rsrvFreePutNotify ( client, pciu->pPutNotify );
|
||||
|
||||
while (TRUE){
|
||||
epicsMutexMustLock(client->eventqLock);
|
||||
@@ -1744,11 +1864,7 @@ LOCAL int clear_channel_reply ( caHdrLargeArray *mp, void *pPayload, struct clie
|
||||
SEND_UNLOCK(client);
|
||||
return RSRV_ERROR;
|
||||
}
|
||||
|
||||
if (pciu->pPutNotify) {
|
||||
free (pciu->pPutNotify);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* send delete confirmed message
|
||||
*/
|
||||
|
||||
@@ -166,7 +166,7 @@ LOCAL int req_server (void)
|
||||
}
|
||||
|
||||
/* listen and accept new connections */
|
||||
if ( listen ( IOC_sock, 10 ) < 0 ) {
|
||||
if ( listen ( IOC_sock, 20 ) < 0 ) {
|
||||
errlogPrintf ("CAS: Listen error\n");
|
||||
socket_close (IOC_sock);
|
||||
epicsThreadSuspendSelf ();
|
||||
@@ -239,6 +239,7 @@ epicsShareFunc int epicsShareAPI rsrv_init (void)
|
||||
freeListInitPvt ( &rsrvChanFreeList, sizeof(struct channel_in_use), 512 );
|
||||
freeListInitPvt ( &rsrvEventFreeList, sizeof(struct event_ext), 512 );
|
||||
freeListInitPvt ( &rsrvSmallBufFreeListTCP, MAX_TCP, 16 );
|
||||
initializePutNotifyFreeList ();
|
||||
|
||||
status = envGetLongConfigParam ( &EPICS_CA_MAX_ARRAY_BYTES, &maxBytesAsALong );
|
||||
if ( status || maxBytesAsALong < 0 ) {
|
||||
@@ -264,7 +265,6 @@ epicsShareFunc int epicsShareAPI rsrv_init (void)
|
||||
}
|
||||
}
|
||||
freeListInitPvt ( &rsrvLargeBufFreeListTCP, rsrvSizeofLargeBufTCP, 1 );
|
||||
|
||||
ellInit ( &beaconAddrList );
|
||||
prsrv_cast_client = NULL;
|
||||
pCaBucket = NULL;
|
||||
@@ -363,10 +363,7 @@ LOCAL void log_one_client (struct client *client, unsigned level)
|
||||
while (pciu){
|
||||
bytes_reserved += sizeof(struct channel_in_use);
|
||||
bytes_reserved += sizeof(struct event_ext)*ellCount(&pciu->eventq);
|
||||
if(pciu->pPutNotify){
|
||||
bytes_reserved += sizeof(*pciu->pPutNotify);
|
||||
bytes_reserved += pciu->pPutNotify->valueSize;
|
||||
}
|
||||
bytes_reserved += rsrvSizeOfPutNotify ( pciu->pPutNotify );
|
||||
pciu = (struct channel_in_use *) ellNext(&pciu->node);
|
||||
}
|
||||
epicsMutexUnlock(client->addrqLock);
|
||||
@@ -449,12 +446,15 @@ void epicsShareAPI casr (unsigned level)
|
||||
freeListItemsAvail ( rsrvSmallBufFreeListTCP );
|
||||
bytes_reserved += rsrvSizeofLargeBufTCP *
|
||||
freeListItemsAvail ( rsrvLargeBufFreeListTCP );
|
||||
bytes_reserved += rsrvSizeOfPutNotify ( 0 ) *
|
||||
freeListItemsAvail ( rsrvPutNotifyFreeList );
|
||||
printf( "There are currently %u bytes on the server's free list\n",
|
||||
bytes_reserved);
|
||||
printf( "%u client(s), %u channel(s), %u event(s) (monitors)\n",
|
||||
printf( "%u client(s), %u channel(s), %u event(s) (monitors) %u putNotify(s)\n",
|
||||
freeListItemsAvail (rsrvClientFreeList),
|
||||
freeListItemsAvail (rsrvChanFreeList),
|
||||
freeListItemsAvail (rsrvEventFreeList));
|
||||
freeListItemsAvail (rsrvEventFreeList),
|
||||
freeListItemsAvail ( rsrvPutNotifyFreeList ));
|
||||
printf( "%u small buffers (%u bytes ea), and %u jumbo buffers (%u bytes ea)\n",
|
||||
freeListItemsAvail ( rsrvSmallBufFreeListTCP ), MAX_TCP,
|
||||
freeListItemsAvail ( rsrvLargeBufFreeListTCP ), rsrvSizeofLargeBufTCP );
|
||||
@@ -601,12 +601,7 @@ void destroy_tcp_client ( struct client *client )
|
||||
}
|
||||
freeListFree (rsrvEventFreeList, pevext);
|
||||
}
|
||||
if (pciu->pPutNotify) {
|
||||
if ( pciu->pPutNotify->busy ) {
|
||||
dbNotifyCancel ( &pciu->pPutNotify->dbPutNotify );
|
||||
}
|
||||
free ( pciu->pPutNotify );
|
||||
}
|
||||
rsrvFreePutNotify ( client, pciu->pPutNotify );
|
||||
LOCK_CLIENTQ;
|
||||
status = bucketRemoveItemUnsignedId ( pCaBucket, &pciu->sid);
|
||||
UNLOCK_CLIENTQ;
|
||||
|
||||
@@ -97,37 +97,22 @@ typedef struct client {
|
||||
char disconnect; /* disconnect detected */
|
||||
} client;
|
||||
|
||||
|
||||
/*
|
||||
* for tracking db put notifies
|
||||
*/
|
||||
typedef struct rsrv_put_notify {
|
||||
ELLNODE node;
|
||||
putNotify dbPutNotify;
|
||||
caHdrLargeArray msg;
|
||||
unsigned valueSize; /* size of block pointed to by dbPutNotify */
|
||||
char busy; /* put notify in progress */
|
||||
char onExtraLaborQueue;
|
||||
} RSRVPUTNOTIFY;
|
||||
|
||||
|
||||
/*
|
||||
* per channel structure
|
||||
* (stored in addrq off of a client block)
|
||||
*/
|
||||
struct channel_in_use {
|
||||
ELLNODE node;
|
||||
ELLLIST eventq;
|
||||
struct client *client;
|
||||
RSRVPUTNOTIFY *pPutNotify; /* potential active put notify */
|
||||
const unsigned cid; /* client id */
|
||||
const unsigned sid; /* server id */
|
||||
epicsTimeStamp time_at_creation; /* for UDP timeout */
|
||||
struct dbAddr addr;
|
||||
ASCLIENTPVT asClientPVT;
|
||||
ELLNODE node;
|
||||
ELLLIST eventq;
|
||||
struct client *client;
|
||||
struct rsrv_put_notify *pPutNotify; /* potential active put notify */
|
||||
const unsigned cid; /* client id */
|
||||
const unsigned sid; /* server id */
|
||||
epicsTimeStamp time_at_creation; /* for UDP timeout */
|
||||
struct dbAddr addr;
|
||||
ASCLIENTPVT asClientPVT;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Event block extension for channel access
|
||||
* some things duplicated for speed
|
||||
@@ -177,6 +162,7 @@ GLBLTYPE void *rsrvEventFreeList;
|
||||
GLBLTYPE void *rsrvSmallBufFreeListTCP;
|
||||
GLBLTYPE void *rsrvLargeBufFreeListTCP;
|
||||
GLBLTYPE unsigned rsrvSizeofLargeBufTCP;
|
||||
GLBLTYPE void *rsrvPutNotifyFreeList;
|
||||
|
||||
#define CAS_HASH_TABLE_SIZE 4096
|
||||
|
||||
@@ -191,7 +177,7 @@ void cas_send_bs_msg ( struct client *pclient, int lock_needed );
|
||||
void cas_send_dg_msg ( struct client *pclient );
|
||||
int rsrv_online_notify_task (void);
|
||||
int cast_server (void);
|
||||
struct client *create_client ();
|
||||
struct client *create_client ( SOCKET sock, int proto );
|
||||
void destroy_client ( struct client * );
|
||||
struct client *create_tcp_client ( SOCKET sock );
|
||||
void destroy_tcp_client ( struct client * );
|
||||
@@ -200,6 +186,10 @@ int camessage ( struct client *client );
|
||||
void write_notify_reply ( void *pArg );
|
||||
int rsrvCheckPut ( const struct channel_in_use *pciu );
|
||||
int rsrv_version_reply ( struct client *client );
|
||||
void rsrvFreePutNotify ( struct client *pClient,
|
||||
struct rsrv_put_notify *pNotify );
|
||||
void initializePutNotifyFreeList (void);
|
||||
unsigned rsrvSizeOfPutNotify ( struct rsrv_put_notify *pNotify );
|
||||
|
||||
/*
|
||||
* inclming protocol maintetnance
|
||||
|
||||
Reference in New Issue
Block a user