From 917fc65c85c912cab2d894f030b11ccf5f5f2f3a Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Fri, 19 Feb 1993 17:03:52 +0000 Subject: [PATCH] CA performance improvement --- src/ca/V5_vxWorks_patch.c | 2 +- src/ca/access.c | 359 +++++++++++++++++++++++++++++--------- src/ca/acctst.c | 11 +- src/ca/ca_printf.c | 2 +- src/ca/catime.c | 139 ++++++++++++--- src/ca/conn.c | 46 +++-- src/ca/convert.c | 2 +- src/ca/flow_control.c | 21 ++- src/ca/gsd_sync_subr.c | 7 +- src/ca/iocinf.c | 120 +++++++++---- src/ca/iocinf.h | 27 ++- src/ca/iocmsg.h | 2 +- src/ca/net_convert.h | 2 +- src/ca/os_depen.h | 51 ++++-- src/ca/repeater.c | 13 +- src/ca/service.c | 76 +++++--- src/ca/test_event.c | 2 +- src/rsrv/camessage.c | 22 +-- src/rsrv/camsgtask.c | 41 ++++- src/rsrv/caserverio.c | 2 +- src/rsrv/caservertask.c | 27 +-- src/rsrv/cast_server.c | 10 +- src/rsrv/globalsource.c | 2 +- src/rsrv/online_notify.c | 11 +- src/rsrv/rsrv_init.c | 2 +- src/rsrv/server.h | 2 +- 26 files changed, 737 insertions(+), 264 deletions(-) diff --git a/src/ca/V5_vxWorks_patch.c b/src/ca/V5_vxWorks_patch.c index 3565102b3..c15eb4982 100644 --- a/src/ca/V5_vxWorks_patch.c +++ b/src/ca/V5_vxWorks_patch.c @@ -1,6 +1,6 @@ #ifdef V5_vxWorks -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)V5_vxWorks_patch.c 1.2\t7/27/92"; #include #include diff --git a/src/ca/access.c b/src/ca/access.c index d7a97c622..9bd224802 100644 --- a/src/ca/access.c +++ b/src/ca/access.c @@ -74,6 +74,14 @@ /* 060392 joh added ca_host_name() */ /* 072792 joh better messages */ /* 072792 joh wrote ca_test_io() */ +/* 102992 joh I notice that the vxWorks FP task option cant */ +/* be modified after task creation so CA now wont */ +/* init if the task does not have the FP opt set */ +/* 111892 joh handle the case where no broadcast interface */ +/* is available better */ +/* 111992 joh added new arg to db_start_events() call */ +/* 120992 joh switched to dll list routines */ +/* 122192 joh increment outstanding ack count */ /* */ /*_begin */ /************************************************************************/ @@ -186,9 +194,13 @@ static char *sccsId = "$Id$\t$Date$"; } #define INITCHK \ -if(!ca_static) \ - ca_task_initialize(); - +if(!ca_static){ \ + int s; \ + s = ca_task_initialize(); \ + if(s != ECA_NORMAL){ \ + return s; \ + } \ +} static struct extmsg nullmsg; @@ -199,7 +211,7 @@ void ca_default_exception_handler(); void *db_init_events(); void ca_default_exception_handler(); void spawn_repeater(); -void check_for_fp(); +int check_for_fp(); void issue_get_callback(); void ca_event_handler(); void ca_pend_io_cleanup(); @@ -221,23 +233,70 @@ void ca_process_exit(); * return a pointer to reserved message buffer space or * nill if the message will not fit * + * LOCK should be on * */ +#if 0 +static +#endif struct extmsg *cac_alloc_msg(piiu, extsize) struct ioc_in_use *piiu; unsigned extsize; { - unsigned msgsize = sizeof(*cac_alloc_msg())+extsize; + unsigned msgsize; + unsigned msglimit; struct extmsg *pmsg; - if(piiu->send->stk+msgsize > piiu->max_msg){ + msgsize = sizeof(struct extmsg)+extsize; + + /* + * dont allow client to send enough messages to + * to get into a deadlock + */ + if(piiu->outstanding_ack_count > ((unsigned)0)){ + unsigned max1; + unsigned size; + int rcva; + + rcva = RECV_ACTIVE(piiu); + + size = piiu->tcp_send_buff_size; + if(rcva){ + max1=size<<2; + } + else{ + max1=size<<1; + } + + if(piiu->bytes_pushing_an_ack > max1){ + if(rcva){ + return NULL; + } + + while(piiu->outstanding_ack_count>0){ + cac_send_msg(); + UNLOCK; + TCPDELAY; + LOCK; + } + } + piiu->bytes_pushing_an_ack += msgsize; + } + + msglimit = piiu->max_msg - msgsize; + if(piiu->send->stk > msglimit){ cac_send_msg(); - if(piiu->send->stk+msgsize > piiu->max_msg){ + if(piiu->send->stk > msglimit){ + if(piiu->outstanding_ack_count > 0){ + piiu->bytes_pushing_an_ack -= msgsize; + } return NULL; } } + pmsg = (struct extmsg *) (piiu->send->buf + piiu->send->stk); pmsg->m_postsize = extsize; + return pmsg; } @@ -249,7 +308,7 @@ unsigned extsize; * */ ca_task_initialize -#ifdef VAXC +#ifdef __STDC__ (void) #else () @@ -259,15 +318,20 @@ ca_task_initialize if (!ca_static) { - if (repeater_installed()==FALSE) { - spawn_repeater(); - } #ifdef vxWorks - check_for_fp(); + status = check_for_fp(); + if(status != ECA_NORMAL){ + return status; + } + if (ca_add_task_variable()<0) return ECA_ALLOCMEM; #endif + if (repeater_installed()==FALSE) { + spawn_repeater(); + } + ca_static = (struct ca_static *) calloc(1, sizeof(*ca_static)); if (!ca_static) abort(); @@ -294,6 +358,8 @@ ca_task_initialize ca_static->ca_tid = taskIdSelf(); + ca_static->ca_local_ticks = LOCALTICKS; + FASTLOCKINIT(&client_lock); FASTLOCKINIT(&event_lock); #ifdef V5_vxWorks @@ -315,10 +381,11 @@ ca_task_initialize taskName(VXTHISTASKID), sizeof(name) - strlen(name) - 1); status = db_start_events( - evuser, - name, - ca_import, - taskIdSelf()); + evuser, + name, + ca_import, + taskIdSelf(), + -1); /* higher priority */ if (status != OK) abort(); } @@ -415,7 +482,7 @@ spawn_repeater() * */ #ifdef vxWorks -static void +static int check_for_fp() { { @@ -424,17 +491,10 @@ check_for_fp() if (taskOptionsGet(taskIdSelf(), &options) == ERROR) abort(); if (!(options & VX_FP_TASK)) { - ca_signal(ECA_NEEDSFP, NULL); - - if (taskOptionsSet( - taskIdSelf(), - VX_FP_TASK, - VX_FP_TASK) == ERROR) - { - abort(); - } + return ECA_NEEDSFP; } } + return ECA_NORMAL; } #endif @@ -451,6 +511,11 @@ ca_import(tid) int status; struct ca_static *pcas; + status = check_for_fp(); + if(status != ECA_NORMAL){ + return status; + } + pcas = (struct ca_static *) taskVarGet(tid, &ca_static); @@ -463,7 +528,6 @@ ca_import(tid) ca_static = pcas; - check_for_fp(); return ECA_NORMAL; } @@ -537,7 +601,7 @@ ca_add_task_variable() * exit- ca_task_exit() is also executed routinely at task exit. */ ca_task_exit -#ifdef VAXC +#ifdef __STDC__ (void) #else () @@ -642,6 +706,7 @@ ca_process_exit() ca_temp = ca_static; # endif + /* if allready in the exit state just NOOP */ # ifdef vxWorks if (!vxTas(&ca_temp->ca_exit_in_progress)) @@ -657,7 +722,13 @@ ca_process_exit() logMsg("ca_task_exit: Removing task %x from CA\n", tid); # endif + /* + * force this macro to use ca_temp + */ +# define ca_static ca_temp LOCK; +# undef ca_static + /* * Fist I must stop any source of further activity on vxWorks */ @@ -687,7 +758,7 @@ ca_process_exit() # ifdef vxWorks chix = (chid) & ca_temp->ca_local_chidlist; while (chix = (chid) chix->node.next){ - while (monix = (evid) lstGet(&chix->eventq)) { + while (monix = (evid) dllGet(&chix->eventq)) { status = db_cancel_event(monix + 1); if (status == ERROR) abort(); @@ -709,7 +780,7 @@ ca_process_exit() "could not close event facility by id"); } - lstFree(&ca_temp->ca_lcl_buff_list); + dllFree(&ca_temp->ca_lcl_buff_list); # endif /* @@ -733,8 +804,8 @@ ca_process_exit() * remove remote chid blocks and event blocks */ for (i = 0; i < ca_temp->ca_nxtiiu; i++) { - while (chix = (chid) lstGet(&ca_temp->ca_iiu[i].chidlist)) { - while (monix = (evid) lstGet(&chix->eventq)) { + while (chix = (chid) dllGet(&ca_temp->ca_iiu[i].chidlist)) { + while (monix = (evid) dllGet(&chix->eventq)) { free((char *)monix); } free((char *)chix); @@ -745,17 +816,22 @@ ca_process_exit() * remove local chid blocks, paddr blocks, waiting ev blocks */ # ifdef vxWorks - while (chix = (chid) lstGet(&ca_temp->ca_local_chidlist)) + while (chix = (chid) dllGet(&ca_temp->ca_local_chidlist)) free((char *)chix); - lstFree(&ca_temp->ca_dbfree_ev_list); + dllFree(&ca_temp->ca_dbfree_ev_list); # endif /* remove remote waiting ev blocks */ - lstFree(&ca_temp->ca_free_event_list); + dllFree(&ca_temp->ca_free_event_list); /* remove any pending read blocks */ - lstFree(&ca_temp->ca_pend_read_list); + dllFree(&ca_temp->ca_pend_read_list); + /* + * force this macro to use ca_temp + */ +# define ca_static ca_temp UNLOCK; +# undef ca_static # if defined(vxWorks) if(FASTLOCKFREE(&ca_temp->ca_client_lock) < 0) @@ -811,7 +887,7 @@ ca_process_exit() * */ ca_build_and_connect -#ifdef VAXC +#ifdef __STDC__ ( char *name_str, chtype get_type, @@ -891,7 +967,7 @@ ca_build_and_connect chix->paddr)->no_elements; chix->iocix = LOCAL_IIU; chix->state = cs_conn; - lstInit(&chix->eventq); + dllInit(&chix->eventq); strncpy(chix + 1, name_str, strcnt); /* check for just a search */ @@ -909,7 +985,7 @@ ca_build_and_connect } } LOCK; - lstAdd(&local_chidlist, chix); + dllAdd(&local_chidlist, chix); UNLOCK; if (chix->connection_func) { @@ -925,7 +1001,10 @@ ca_build_and_connect } #endif - if (ca_static->ca_cast_available) { + if (!ca_static->ca_cast_available) { + status = ECA_NOCAST; + } + else{ /* allocate CHIU (channel in use) block */ /* also allocate enough for the channel name */ *chixptr = chix = (chid) malloc(sizeof(*chix) + strcnt); @@ -955,12 +1034,12 @@ ca_build_and_connect chix->build_value = (void *) pvalue; chix->name_length = strcnt; chix->state = cs_never_conn; - lstInit(&chix->eventq); + dllInit(&chix->eventq); /* Save this channels name for retry if required */ strncpy(chix + 1, name_str, strcnt); - lstAdd(&iiu[BROADCAST_IIU].chidlist, chix); + dllAdd(&iiu[BROADCAST_IIU].chidlist, chix); /* * set the conn tries back to zero so this channel's location * can be found @@ -1012,6 +1091,10 @@ void build_msg(chix, reply_type) } mptr = CAC_ALLOC_MSG(piiu, size); + if(!mptr){ + ca_printf("%s: %s\n",__FILE__,ca_message(ECA_TOLARGE)); + return; + } mptr->m_cmmd = htons(cmd); mptr->m_available = (int) chix; @@ -1049,7 +1132,7 @@ void build_msg(chix, reply_type) * */ ca_array_get -#ifdef VAXC +#ifdef __STDC__ ( chtype type, unsigned int count, @@ -1066,6 +1149,7 @@ ca_array_get { register struct extmsg *mptr; unsigned size=0; + struct ioc_in_use *piiu; CHIXCHK(chix); @@ -1095,7 +1179,12 @@ ca_array_get #endif LOCK; - mptr = CAC_ALLOC_MSG(&iiu[chix->iocix], size); + piiu = &iiu[chix->iocix]; + mptr = CAC_ALLOC_MSG(piiu, size); + if(!mptr){ + UNLOCK; + return ECA_TOLARGE; + } /* * msg header only on db read req @@ -1106,7 +1195,14 @@ ca_array_get mptr->m_count = htons(count); mptr->m_pciu = chix->paddr; - CAC_ADD_MSG(&iiu[chix->iocix]); + CAC_ADD_MSG(piiu); + + /* + * keep track of the number of messages + * outstanding on this connection that + * require a response + */ + piiu->outstanding_ack_count++; UNLOCK; SETPENDRECV; @@ -1123,7 +1219,7 @@ ca_array_get * */ ca_array_get_callback -#ifdef VAXC +#ifdef __STDC__ ( chtype type, unsigned int count, @@ -1167,7 +1263,7 @@ ca_array_get_callback #endif LOCK; - if (!(monix = (evid) lstGet(&free_event_list))) + if (!(monix = (evid) dllGet(&free_event_list))) monix = (evid) malloc(sizeof *monix); if (monix) { @@ -1178,7 +1274,7 @@ ca_array_get_callback monix->type = type; monix->count = count; - lstAdd(&pend_read_list, monix); + dllAdd(&pend_read_list, monix); issue_get_callback(monix); @@ -1228,6 +1324,10 @@ issue_get_callback(monix) } mptr = CAC_ALLOC_MSG(piiu, size); + if(!mptr){ + ca_printf("%s: %s\n",__FILE__,ca_message(ECA_TOLARGE)); + return; + } /* msg header only on db read notify req */ mptr->m_cmmd = htons(IOC_READ_NOTIFY); @@ -1238,6 +1338,13 @@ issue_get_callback(monix) CAC_ADD_MSG(piiu); + /* + * keep track of the number of messages + * outstanding on this connection that + * require a response + */ + piiu->outstanding_ack_count++; + piiu->send_needed = TRUE; } @@ -1248,7 +1355,7 @@ issue_get_callback(monix) * */ ca_array_put -#ifdef VAXC +#ifdef __STDC__ ( chtype type, unsigned int count, @@ -1333,6 +1440,11 @@ register void *pvalue; LOCK; mptr = CAC_ALLOC_MSG(&iiu[chix->iocix], postcnt); + if(!mptr){ + UNLOCK; + return ECA_TOLARGE; + } + pdest = (void *)(mptr+1); @@ -1400,7 +1512,7 @@ register void *pvalue; * */ ca_change_connection_event -#ifdef VAXC +#ifdef __STDC__ ( chid chix, void (*pfunc)() @@ -1443,7 +1555,7 @@ void (*pfunc)(); * */ ca_add_exception_event -#ifdef VAXC +#ifdef __STDC__ ( void (*pfunc)(), void *arg @@ -1481,7 +1593,7 @@ void *arg; * */ ca_add_io_event -#ifdef VAXC +#ifdef __STDC__ ( void (*ast)(), void *astarg @@ -1505,7 +1617,7 @@ void *astarg; return ECA_ALLOCMEM; pioe->io_done_arg = astarg; pioe->io_done_sub = ast; - lstAdd(&ioeventlist,pioe); + dllAdd(&ioeventlist,pioe); UNLOCK; } @@ -1521,7 +1633,7 @@ void *astarg; * */ ca_add_masked_array_event -#ifdef VAXC +#ifdef __STDC__ ( chtype type, unsigned int count, @@ -1575,15 +1687,15 @@ unsigned mask; dbevsize = db_sizeof_event_block(); - if(!(monix = (evid)lstGet(&dbfree_ev_list))) + if(!(monix = (evid)dllGet(&dbfree_ev_list))) monix = (evid)malloc(sizeof(*monix)+dbevsize); } else - if(!(monix = (evid)lstGet(&free_event_list))) + if(!(monix = (evid)dllGet(&free_event_list))) monix = (evid)malloc(sizeof *monix); } # else - if(!(monix = (evid)lstGet(&free_event_list))) + if(!(monix = (evid)dllGet(&free_event_list))) monix = (evid) malloc(sizeof *monix); # endif @@ -1628,7 +1740,7 @@ unsigned mask; is no chance that it will be deleted at exit before it is completely created */ - lstAdd(&chix->eventq, monix); + dllAdd(&chix->eventq, monix); /* force event to be called at least once @@ -1649,7 +1761,7 @@ unsigned mask; /* It can be added to the list any place if it is remote */ /* Place in the channel list */ - lstAdd(&chix->eventq, monix); + dllAdd(&chix->eventq, monix); ca_request_event(monix); @@ -1700,6 +1812,10 @@ ca_request_event(monix) } mptr = (struct monops *) CAC_ALLOC_MSG(piiu, size); + if(!mptr){ + ca_printf("%s: %s\n",__FILE__,ca_message(ECA_TOLARGE)); + return; + } /* msg header */ mptr->m_header.m_cmmd = htons(IOC_EVENT_ADD); @@ -1780,7 +1896,7 @@ void *pfl; pbuf = (struct tmp_buff *) lcl_buff_list.node.next; if(pbuf->size >= size){ - lstDelete( + dllDelete( &lcl_buff_list, pbuf); }else @@ -1860,7 +1976,7 @@ void *pfl; if(ptbuf) ptbuf = (struct tmp_buff *) ptbuf->node.previous; - lstInsert( + dllInsert( &lcl_buff_list, ptbuf, pbuf); @@ -1889,7 +2005,7 @@ void *pfl; * */ ca_clear_event -#ifdef VAXC +#ifdef __STDC__ (register evid monix) #else (monix) @@ -1912,16 +2028,16 @@ ca_clear_event * dont allow two threads to delete the same moniitor at once */ LOCK; - status = lstFind(&chix->eventq, monix); + status = dllFind(&chix->eventq, monix); if (status != ERROR) { - lstDelete(&chix->eventq, monix); + dllDelete(&chix->eventq, monix); status = db_cancel_event(monix + 1); } UNLOCK; if (status == ERROR) return ECA_BADMONID; - lstAdd(&dbfree_ev_list, monix); + dllAdd(&dbfree_ev_list, monix); return ECA_NORMAL; } @@ -1935,7 +2051,15 @@ ca_clear_event */ LOCK; if(chix->state == cs_conn){ - mptr = CAC_ALLOC_MSG(&iiu[chix->iocix], 0); + struct ioc_in_use *piiu; + + piiu = &iiu[chix->iocix]; + + mptr = CAC_ALLOC_MSG(piiu, 0); + if(!mptr){ + UNLOCK; + return ECA_TOLARGE; + } /* msg header */ mptr->m_cmmd = htons(IOC_EVENT_CANCEL); @@ -1948,10 +2072,16 @@ ca_clear_event * NOTE: I free the monitor block only * after confirmation from IOC */ - CAC_ADD_MSG(&iiu[chix->iocix]); + CAC_ADD_MSG(piiu); + + /* + * keep track of the number of messages outstanding on this + * connection that require a response + */ + piiu->outstanding_ack_count++; } else{ - lstDelete(&monix->chan->eventq, monix); + dllDelete(&monix->chan->eventq, monix); } UNLOCK; @@ -1974,7 +2104,7 @@ ca_clear_event * */ ca_clear_channel -#ifdef VAXC +#ifdef __STDC__ (register chid chix) #else (chix) @@ -2015,17 +2145,17 @@ ca_clear_channel /* * clear out the events for this channel */ - while (monix = (evid) lstGet(&chix->eventq)) { + while (monix = (evid) dllGet(&chix->eventq)) { status = db_cancel_event(monix + 1); if (status == ERROR) abort(); - lstAdd(&dbfree_ev_list, monix); + dllAdd(&dbfree_ev_list, monix); } /* * clear out this channel */ - lstDelete(&local_chidlist, chix); + dllDelete(&local_chidlist, chix); free((char *) chix); break; /* to unlock exit */ @@ -2039,8 +2169,8 @@ ca_clear_channel * check for conn state while locked to avoid a race */ if(old_chan_state != cs_conn){ - lstConcat(&free_event_list, &chix->eventq); - lstDelete(&piiu->chidlist, chix); + dllConcat(&free_event_list, &chix->eventq); + dllDelete(&piiu->chidlist, chix); if (chix->iocix != BROADCAST_IIU && !piiu->chidlist.count){ close_ioc(piiu); @@ -2053,7 +2183,11 @@ ca_clear_channel * clear events and all other resources for this chid on the * IOC */ - mptr = CAC_ALLOC_MSG(&iiu[chix->iocix], 0); + mptr = CAC_ALLOC_MSG(piiu, 0); + if(!mptr){ + UNLOCK; + return ECA_TOLARGE; + } /* msg header */ mptr->m_cmmd = htons(IOC_CLEAR_CHANNEL); @@ -2067,7 +2201,14 @@ ca_clear_channel * confirmation from IOC */ - CAC_ADD_MSG(&iiu[chix->iocix]); + CAC_ADD_MSG(piiu); + + /* + * keep track of the number of messages + * outstanding on this connection that + * require a response + */ + piiu->outstanding_ack_count++; break; /* to unlock exit */ } @@ -2103,7 +2244,7 @@ ca_clear_channel /* IO completes. */ /* ca_flush_io() is called by this routine. */ /************************************************************************/ -#ifdef VAXC +#ifdef __STDC__ ca_pend(ca_real timeout, int early) #else ca_pend(timeout, early) @@ -2238,6 +2379,7 @@ int early; * send a sync to each IOC and back. dont * count reads until we recv the sync * + * LOCK must be on */ static void ca_pend_io_cleanup() @@ -2253,9 +2395,20 @@ ca_pend_io_cleanup() piiu->cur_read_seq++; mptr = CAC_ALLOC_MSG(piiu, 0); + if(!mptr){ + ca_printf("%s: %s\n",__FILE__,ca_message(ECA_TOLARGE)); + return; + } + *mptr = nullmsg; mptr->m_cmmd = htons(IOC_READ_SYNC); CAC_ADD_MSG(piiu); + /* + * keep track of the number of messages + * outstanding on this connection that + * require a response + */ + piiu->outstanding_ack_count++; } } pndrecvcnt = 0; @@ -2270,7 +2423,7 @@ ca_pend_io_cleanup() * */ ca_flush_io -#ifdef VAXC +#ifdef __STDC__ (void) #else () @@ -2309,9 +2462,34 @@ int ca_test_io() * * */ +#ifdef __STDC__ +void ca_signal(long ca_status,char *message) +#else void ca_signal(ca_status,message) +long ca_status; +char *message; +#endif +{ + ca_signal_with_file_and_lineno(ca_status, message, NULL, 0); +} + + +/* + * ca_signal_with_file_and_lineno() + */ +#ifdef __STDC__ +void ca_signal_with_file_and_lineno( +long ca_status, +char *message, +char *pfilenm, +int lineno) +#else +void ca_signal_with_file_and_lineno(ca_status,message,pfilenm,lineno) int ca_status; char *message; +char *pfilenm; +unsigned lineno; +#endif { static char *severity[] = { @@ -2345,6 +2523,13 @@ char *message; ca_printf( " Severity: [%s]\n", severity[CA_EXTRACT_SEVERITY(ca_status)]); + if(pfilenm){ + ca_printf( +" Source File: [%s] Line Number: [%d]\n", + pfilenm, + lineno); + } + /* * * @@ -2392,6 +2577,11 @@ ca_busy_message(piiu) LOCK; mptr = CAC_ALLOC_MSG(piiu, 0); + if(!mptr){ + UNLOCK; + ca_printf("%s: %s\n",__FILE__,ca_message(ECA_TOLARGE)); + return; + } *mptr = nullmsg; mptr->m_cmmd = htons(IOC_EVENTS_OFF); CAC_ADD_MSG(piiu); @@ -2418,6 +2608,11 @@ ca_ready_message(piiu) LOCK; mptr = CAC_ALLOC_MSG(piiu, 0); + if(!mptr){ + UNLOCK; + ca_printf("%s: %s\n",__FILE__,ca_message(ECA_TOLARGE)); + return; + } *mptr = nullmsg; mptr->m_cmmd = htons(IOC_EVENTS_ON); CAC_ADD_MSG(piiu); @@ -2438,6 +2633,10 @@ noop_msg(piiu) struct extmsg *mptr; mptr = CAC_ALLOC_MSG(piiu, 0); + if(!mptr){ + ca_printf("%s: %s\n",__FILE__,ca_message(ECA_TOLARGE)); + return; + } *mptr = nullmsg; mptr->m_cmmd = htons(IOC_NOOP); CAC_ADD_MSG(piiu); @@ -2463,6 +2662,10 @@ chid pchan; return; mptr = CAC_ALLOC_MSG(piiu, 0); + if(!mptr){ + ca_printf("%s: %s\n",__FILE__,ca_message(ECA_TOLARGE)); + return; + } *mptr = nullmsg; mptr->m_cmmd = htons(IOC_CLAIM_CIU); mptr->m_pciu = pchan->paddr; diff --git a/src/ca/acctst.c b/src/ca/acctst.c index 72e7becee..433b957f6 100644 --- a/src/ca/acctst.c +++ b/src/ca/acctst.c @@ -4,7 +4,7 @@ static char *sccsId = "$Id$\t$Date$"; * CA test/debug routine */ -#if 0 +#if 1 #define CA_TEST_CHNL "ca:ai_2000" #define CA_TEST_CHNL4 "ca:ai_2000" #else @@ -63,18 +63,11 @@ main() void null_event(); struct dbr_gr_float *ptr; struct dbr_gr_float *pgrfloat; - float delay = .003; - long status; - long pid; long i, j; - float delta = 1.0; evid monix; - char string[41]; - float value; float *pfloat; double *pdouble; - struct dbr_ctrl_float *pctrl; char pstring[NUM][MAX_STRING_SIZE]; void write_event(); void conn(); @@ -240,7 +233,7 @@ main() for(i=0; i diff --git a/src/ca/catime.c b/src/ca/catime.c index 31112cdd3..d9d545c4a 100644 --- a/src/ca/catime.c +++ b/src/ca/catime.c @@ -19,8 +19,8 @@ /* System includes */ -#include #ifdef vxWorks +#include #include #endif @@ -28,67 +28,97 @@ #include #include -#define CA_TEST_CHNL "AI_2000" +#ifndef OK +#define OK 0 +#endif +#ifndef NULL +#define NULL 0 +#endif -#ifdef vxWorks -spcatime() -{ - int acctst(); +#ifndef min +#define min(A,B) ((A)>(B)?(B):(A)) +#endif - return taskSpawn("acctst",200,VX_FP_TASK,20000,acctst); -} +#ifndef NELEMENTS +#define NELEMENTS(A) (sizeof (A) / sizeof ((A) [0])) #endif #define NUM 1 +#define ITERATION_COUNT 10000 -catime() +#define WAIT_FOR_ACK + +chid chan_list[min(10000,ITERATION_COUNT)]; + +#ifndef vxWorks +main(argc, argv) +int argc; +char **argv; +{ + char *pname; + + if(argc == 2){ + pname = argv[1]; + catime(pname); + } + else{ + printf("usage: %s ", argv[0]); + } +} +#endif + +catime(channelName) +char *channelName; { chid ai_1; long status; long i,j; void *ptr; - int ca_array_put(); - int ca_array_get(); - + int test_search(), test_free(); SEVCHK(ca_task_initialize(),"Unable to initialize"); - SEVCHK(ca_search(CA_TEST_CHNL,&ai_1),NULL); + SEVCHK(ca_search(channelName,&ai_1),NULL); status = ca_pend_io(5.0); SEVCHK(status,NULL); if(status == ECA_TIMEOUT) - exit(); + exit(OK); ptr = (void *) malloc(NUM*sizeof(union db_access_val)+NUM*MAX_STRING_SIZE); if(!ptr) - exit(); + exit(OK); printf("channel name %s native type %d native count %d\n",ai_1+1,ai_1->type,ai_1->count); + printf("search test\n"); + timex(test_search,channelName); + printf("free test\n"); + timex(test_free,ai_1); for(i=0;i' */ /* */ /*_begin */ /************************************************************************/ @@ -37,6 +39,7 @@ static char *sccsId = "$Id$\t$Date$"; # include #elif defined(VMS) #elif defined(vxWorks) +#include #else @@@@ dont compile @@@@ #endif @@ -46,7 +49,6 @@ static char *sccsId = "$Id$\t$Date$"; #include #include - /* * @@ -65,7 +67,6 @@ char silent; register unsigned int retry_cnt = 0; register unsigned int keepalive_cnt = 0; unsigned int retry_cnt_no_handler = 0; - char string[128]; ca_time current; int i; @@ -75,13 +76,13 @@ char silent; int search_type; if(iiu[i].next_retry == CA_CURRENT_TIME){ - if(iiu[i].conn_up){ + if(!iiu[i].conn_up || i==BROADCAST_IIU){ iiu[i].next_retry = - current + CA_RETRY_PERIOD; + current + iiu[i].retry_delay; } else{ iiu[i].next_retry = - current + iiu[i].retry_delay; + current + CA_RETRY_PERIOD; } continue; } @@ -100,7 +101,15 @@ char silent; */ noop_msg(&iiu[i]); keepalive_cnt++; - continue; + + /* + * allow execution to continue through + * the connection retry code below + * since we may be connected while + * some channels which have not been + * verified to exist on the recently + * booted IOC. + */ } if(iiu[i].nconn_tries++ > MAXCONNTRIES) @@ -119,14 +128,14 @@ char silent; retry_cnt++; if(!(silent || chix->connection_func)){ - ca_signal(ECA_CHIDNOTFND, chix+1); + ca_signal(ECA_CHIDNOTFND, (char *)(chix+1)); retry_cnt_no_handler++; } } } if(retry_cnt){ - ca_printf(" "); + ca_printf(" ", retry_cnt); #ifdef UNIX fflush(stdout); #endif @@ -209,9 +218,9 @@ struct in_addr *pnet_addr; */ /* - * reset the retry cnt to 3 + * reset the retry cnt */ - iiu[BROADCAST_IIU].nconn_tries = MAXCONNTRIES-3; + iiu[BROADCAST_IIU].nconn_tries = 0; /* * This part is very important since many machines @@ -238,10 +247,19 @@ struct in_addr *pnet_addr; port = saddr.sin_port; } - iiu[BROADCAST_IIU].retry_delay = - (port&0xf) + CA_RECAST_DELAY; - iiu[BROADCAST_IIU].next_retry = - time(NULL) + iiu[BROADCAST_IIU].retry_delay; + { + int delay; + int next; + + delay = (port&CA_RECAST_PORT_MASK) + CA_RECAST_PERIOD; + iiu[BROADCAST_IIU].retry_delay = + min(iiu[BROADCAST_IIU].retry_delay, delay); + + next = time(NULL) + iiu[BROADCAST_IIU].retry_delay; + iiu[BROADCAST_IIU].next_retry = + min(next, iiu[BROADCAST_IIU].next_retry); + } + #ifdef DEBUG ca_printf("CAC: ", iiu[BROADCAST_IIU].retry_delay); diff --git a/src/ca/convert.c b/src/ca/convert.c index 3b34c3455..0130a9818 100644 --- a/src/ca/convert.c +++ b/src/ca/convert.c @@ -26,7 +26,7 @@ * */ -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)convert.c 1.5\t7/27/92"; #include diff --git a/src/ca/flow_control.c b/src/ca/flow_control.c index 61cf74d53..dd7d4e5ff 100644 --- a/src/ca/flow_control.c +++ b/src/ca/flow_control.c @@ -48,7 +48,12 @@ static char *sccsId = "$Id$\t$Date$"; #elif defined(VMS) # include # include -# include +# if defined(UCX) /* GeG 09-DEC-1992 */ +# include +# include +# else +# include +# endif #elif defined(UNIX) # include # include @@ -79,6 +84,10 @@ flow_control(piiu) register int status; register int busy = piiu->client_busy; + /* + * use of the additional system call here does not + * seem to slow things down appreciably + */ status = socket_ioctl(piiu->sock_chan, FIONREAD, &nbytes); @@ -87,6 +96,10 @@ flow_control(piiu) return; } + /* + * I wish to avoid going into flow control however + * as this impacts the performance of batched fetches + */ if (nbytes) { piiu->contiguous_msg_count++; if (!busy) @@ -94,10 +107,16 @@ flow_control(piiu) MAX_CONTIGUOUS_MSG_COUNT) { piiu->client_busy = TRUE; ca_busy_message(piiu); +# if DEBUG + printf("fc on\n"); +# endif } } else { piiu->contiguous_msg_count = 0; if (busy) { +# ifdef DEBUG + printf("fc off\n"); +# endif ca_ready_message(piiu); piiu->client_busy = FALSE; } diff --git a/src/ca/gsd_sync_subr.c b/src/ca/gsd_sync_subr.c index c416c63e1..db8f95366 100644 --- a/src/ca/gsd_sync_subr.c +++ b/src/ca/gsd_sync_subr.c @@ -81,7 +81,7 @@ *************************************************** */ -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)gsd_sync_subr.c 1.8\t11/5/92"; #if defined(UNIX) # include @@ -160,7 +160,7 @@ struct gsd_sync_compctrl { }; /*---------------------------------------------*/ -#define ONESEC_IN_TICKS 60 +#define ONESEC_IN_TICKS (sysClkRateGet()) #define PEND_EVENT_DELAY 0.0001 /* standard 0.0001sec event delay */ #define USEC_TIME_OUT 100 /* 100 usec timeval's timeout */ @@ -601,7 +601,7 @@ float timeout_secs; if(NULL == pCompctrl) { ca_printf("gsd_sync_read: error NULL arg for pCompctrl\n"); - return; + return 0; } if(flag == PREVIOUS_SYNC_DATA) { @@ -1070,7 +1070,6 @@ struct gsd_sync_compctrl *pCompctrl; float timeout_secs; VOID **pfdctx; { - struct gsd_sync_ctrl *pCtrl = pCompctrl->pCtrl; struct timeval new_gmt; struct timezone zone; diff --git a/src/ca/iocinf.c b/src/ca/iocinf.c index b385ec03f..a0e87e018 100644 --- a/src/ca/iocinf.c +++ b/src/ca/iocinf.c @@ -1,4 +1,4 @@ - /************************************************************************/ +/************************************************************************/ /* */ /* L O S A L A M O S */ /* Los Alamos National Laboratory */ @@ -37,12 +37,14 @@ /* 072392 joh use SO_REUSEADDR when testing to see */ /* if the repeater has been started */ /* 072792 joh better messages */ +/* 101692 joh defensive coding against unexpected errno's */ +/* 120992 GeG support VMS/UCX */ /* */ /*_begin */ /************************************************************************/ /* */ /* Title: IOC socket interface module */ -/* File: /.../ca/iocinf.c */ +/* File: /.../ca/$Id$ */ /* Environment: VMS. UNIX, vxWorks */ /* Equipment: VAX, SUN, VME */ /* */ @@ -73,12 +75,17 @@ static char *sccsId = "$Id$\t$Date$"; # include # define __TIME /* dont include VMS CC time.h under MULTINET */ # include -# include # include # include # include # include +#if defined(UCX) /* GeG 09-DEC-1992 */ +# include +# include +#else +# include # include +#endif #elif defined(UNIX) # include # include @@ -274,7 +281,6 @@ struct ioc_in_use *piiu; return ECA_SOCK; } -#ifdef KEEPALIVE /* * This should cause the connection to be checked * periodically and an error to be returned if it is lost? @@ -294,7 +300,6 @@ struct ioc_in_use *piiu; } return ECA_SOCK; } -#endif #ifdef JUNKYARD { @@ -315,11 +320,9 @@ struct ioc_in_use *piiu; } #endif - /* set TCP buffer sizes only if BSD 4.3 sockets */ - /* temporarily turned off */ -#ifdef JUNKYARD - - i = (MAX_MSG_SIZE+sizeof(int)) * 2; +#ifdef CA_SET_TCP_BUFFER_SIZES + /* set TCP buffer sizes */ + i = MAX_MSG_SIZE; status = setsockopt( sock, SOL_SOCKET, @@ -333,6 +336,7 @@ struct ioc_in_use *piiu; } return ECA_SOCK; } + i = MAX_MSG_SIZE; status = setsockopt( sock, SOL_SOCKET, @@ -348,6 +352,22 @@ struct ioc_in_use *piiu; } #endif + /* fetch the TCP send buffer size */ + i = sizeof(piiu->tcp_send_buff_size); + status = getsockopt( + sock, + SOL_SOCKET, + SO_SNDBUF, + &piiu->tcp_send_buff_size, + &i); + if(status < 0 || i != sizeof(piiu->tcp_send_buff_size)){ + status = socket_close(sock); + if(status<0){ + SEVCHK(ECA_INTERNAL,NULL); + } + return ECA_SOCK; + } + /* connect */ status = connect( sock, @@ -457,7 +477,12 @@ struct ioc_in_use *piiu; default: ca_signal(ECA_INTERNAL,"alloc_ioc: ukn protocol\n"); + /* + * turn off gcc warnings + */ + return ECA_INTERNAL; } + /* setup cac_send_msg(), recv_msg() buffers */ if(!piiu->send){ if(! (piiu->send = (struct buffer *) @@ -485,6 +510,7 @@ struct ioc_in_use *piiu; piiu->recv->stk = 0; piiu->conn_up = TRUE; + piiu->active = FALSE; if(fd_register_func){ LOCKEVENTS; (*fd_register_func)(fd_register_arg, sock, TRUE); @@ -584,13 +610,20 @@ notify_ca_repeater() &saddr, sizeof saddr); if(status < 0){ - ca_printf("CAC: notify_ca_repeater: send to lcl addr failed\n"); - abort(); + if( MYERRNO == EINTR || + MYERRNO == ENOBUFS || + MYERRNO == EWOULDBLOCK){ + TCPDELAY; + } + else{ + ca_printf( + "CAC: notify_ca_repeater: send to lcl addr failed\n"); + abort(); + } } } } - /* * CAC_SEND_MSG() @@ -634,9 +667,11 @@ void cac_send_msg() * frees up push pull deadlock only * if recv not already in progress */ -# ifdef UNIX - if(post_msg_active==0) +# if defined(UNIX) + if(post_msg_active==0){ recv_msg_select(¬imeout); + } +# elif defined(vxWorks) # endif done = TRUE; @@ -651,9 +686,6 @@ void cac_send_msg() } } -#ifndef UNIX - break; -#else if(done){ /* * allways double check that we @@ -677,26 +709,31 @@ void cac_send_msg() if(piiu->send->stk){ inaddr = &piiu->sock_addr.sin_addr; iocname = piiu->host_name_str; -#ifdef CLOSE_ON_EXPIRED - ca_signal(ECA_DLCKREST, iocname); - close_ioc(piiu); -#else - ca_signal(ECA_SERVBEHIND, iocname); -#endif +#define CLOSE_ON_EXPIRED /* kill conn if we pend to long on it */ +# ifdef CLOSE_ON_EXPIRED + ca_signal( + ECA_DLCKREST, + iocname); + close_ioc(piiu); +# else + ca_signal( + ECA_SERVBEHIND, + iocname); +# endif } } -#ifndef CLOSE_ON_EXPIRED - retry_count = RETRY_INIT; -#endif +# ifdef CLOSE_ON_EXPIRED + break; +# else + retry_count = RETRY_INIT; +# endif } TCPDELAY; -#endif } send_msg_active--; } - /* * CAC_SEND_MSG_PIIU() @@ -767,8 +804,9 @@ register struct ioc_in_use *piiu; ca_printf("CAC: sent zero ?\n"); TCPDELAY; } -#ifdef UNIX - else if(MYERRNO == EWOULDBLOCK){ + else if(MYERRNO == EWOULDBLOCK || + MYERRNO == ENOBUFS || + MYERRNO == EINTR){ if(pmsg != piiu->send->buf){ /* * realign the message if this @@ -782,7 +820,6 @@ ca_printf("CAC: sent zero ?\n"); return ERROR; } -#endif else{ if( MYERRNO != EPIPE && MYERRNO != ECONNRESET && @@ -865,7 +902,9 @@ struct timeval *ptimeout; text, "CAC: unexpected select fail: %d", MYERRNO); - ca_signal(ECA_INTERNAL,text); } } + ca_signal(ECA_INTERNAL,text); + } + } for(piiu=iiu;piiu<&iiu[nxtiiu];piiu++){ if(piiu->conn_up){ @@ -896,6 +935,7 @@ static void recv_msg(piiu) struct ioc_in_use *piiu; { + piiu->active = TRUE; switch(piiu->sock_proto){ case IPPROTO_TCP: @@ -915,10 +955,12 @@ struct ioc_in_use *piiu; } if(piiu->send_needed){ + LOCK cac_send_msg_piiu(piiu); + UNLOCK } - return; + piiu->active = FALSE; } @@ -952,8 +994,8 @@ struct ioc_in_use *piiu; return; } else if(status <0){ - /* try again on status of -1 and EWOULDBLOCK */ - if(MYERRNO == EWOULDBLOCK){ + /* try again on status of -1 and no luck this time */ + if(MYERRNO == EWOULDBLOCK || MYERRNO == EINTR){ TCPDELAY; return; } @@ -1064,7 +1106,7 @@ struct ioc_in_use *piiu; * op would block which is ok to ignore till ready * later */ - if(MYERRNO == EWOULDBLOCK) + if(MYERRNO == EWOULDBLOCK || MYERRNO == EINTR) break; ca_signal(ECA_INTERNAL,"unexpected udp recv error"); } @@ -1237,7 +1279,8 @@ struct ioc_in_use *piiu; int status; if(piiu == &iiu[BROADCAST_IIU]){ - ca_signal(ECA_INTERNAL, "Unable to perform UDP broadcast\n"); + ca_signal(ECA_INTERNAL, + "Unable to perform UDP broadcast\n"); } if(!piiu->conn_up) @@ -1251,6 +1294,7 @@ struct ioc_in_use *piiu; piiu->recv->stk = 0; piiu->max_msg = MAX_UDP; piiu->conn_up = FALSE; + piiu->active = FALSE; /* * reset the delay to the next retry diff --git a/src/ca/iocinf.h b/src/ca/iocinf.h index f12dd42c7..9f1d37d7c 100644 --- a/src/ca/iocinf.h +++ b/src/ca/iocinf.h @@ -22,6 +22,11 @@ /* .11 031692 joh added declaration for post_msg() */ /* .12 031892 joh initial rebroadcast delay is now a #define */ /* .13 050492 joh added exception channel fd set */ +/* .14 111792 joh increased MAXCONNTRIES from 3 to 30 */ +/* .15 112092 joh added AST lck count var for VMS */ +/* .16 120992 joh switched to dll list routines */ +/* .17 121892 joh added TCP send buf size var */ +/* .17 122192 joh added outstanding ack var */ /* */ /*_begin */ /************************************************************************/ @@ -69,14 +74,17 @@ static char *iocinfhSccsId = "$Id$\t$Date$"; DONT_COMPILE #endif -#ifndef INClstLibh -# include +#ifndef INCdllLibh +# include #endif #ifndef INCos_depenh # include #endif +#ifndef min +#define min(A,B) ((A)>(B)?(B):(A)) +#endif /* throw out requests prior to last ECA_TIMEOUT from ca_pend */ #define VALID_MSG(PIIU) (piiu->read_seq == piiu->cur_read_seq) @@ -112,8 +120,10 @@ struct pending_io_event{ }; typedef unsigned long ca_time; -#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */ -#define CA_RECAST_DELAY 1 /* initial int sec to next recast */ +#define CA_RETRY_PERIOD 5 /* int sec to next keepalive */ +#define CA_RECAST_DELAY 1 /* initial int sec to next recast */ +#define CA_RECAST_PORT_MASK 0xf /* random retry interval off port */ +#define CA_RECAST_PERIOD 30 /* ll on retry period long term */ #define CA_CURRENT_TIME 0 #define MAX_CONTIGUOUS_MSG_COUNT 2 @@ -152,6 +162,7 @@ typedef unsigned long ca_time; #elif defined(VMS) # define io_done_flag (ca_static->ca_io_done_flag) # define peek_ast_buf (ca_static->ca_peek_ast_buf) +# define ast_lock_count (ca_static->ca_ast_lock_count) #else DONT_COMPILE #endif @@ -182,6 +193,7 @@ struct ca_static{ #elif defined(VMS) int ca_io_done_flag; char ca_peek_ast_buf; + long ca_ast_lock_count; #elif defined(vxWorks) SEM_ID ca_io_done_sem; void *ca_evuser; @@ -192,16 +204,21 @@ struct ca_static{ LIST ca_dbfree_ev_list; LIST ca_lcl_buff_list; int ca_event_tid; + unsigned ca_local_ticks; #else DONT_COMPILE #endif struct ioc_in_use{ + unsigned outstanding_ack_count; + unsigned bytes_pushing_an_ack; unsigned contiguous_msg_count; unsigned client_busy; + char active; int sock_proto; struct sockaddr_in sock_addr; int sock_chan; int max_msg; + int tcp_send_buff_size; struct buffer *send; struct buffer *recv; unsigned read_seq; @@ -213,7 +230,7 @@ struct ca_static{ unsigned nconn_tries; ca_time next_retry; ca_time retry_delay; -#define MAXCONNTRIES 3 +#define MAXCONNTRIES 30 #if defined(VMS) /* for qio ASTs */ struct sockaddr_in recvfrom; struct iosb iosb; diff --git a/src/ca/iocmsg.h b/src/ca/iocmsg.h index 9eee019c3..fc28ac93c 100644 --- a/src/ca/iocmsg.h +++ b/src/ca/iocmsg.h @@ -15,7 +15,7 @@ #define __IOCMSG__ -static char *iocmsghSccsId = "$Id$\t$Date$"; +static char *iocmsghSccsId = "@(#)iocmsg.h 1.5\t7/27/92"; /* TCP/UDP port number (bumped each protocol change) */ #define CA_PROTOCOL_VERSION 4 diff --git a/src/ca/net_convert.h b/src/ca/net_convert.h index 934b04848..b26ba5b47 100644 --- a/src/ca/net_convert.h +++ b/src/ca/net_convert.h @@ -11,7 +11,7 @@ * */ -static char *net_converthSccsId = "$Id$\t$Date$"; +static char *net_converthSccsId = "@(#)net_convert.h 1.5\t7/27/92"; /************************************************************************/ /* So byte swapping can be performed in line for efficiency */ diff --git a/src/ca/os_depen.h b/src/ca/os_depen.h index 4078b5634..410de1331 100644 --- a/src/ca/os_depen.h +++ b/src/ca/os_depen.h @@ -18,6 +18,11 @@ * .07 joh 120291 added declaration of taskIdCurrent for * compiling with V4 vxWorks * .08 joh 062692 took out printf to logMsg MACRO + * .09 joh 101692 dont quit if select() is interrupted in + * the UNIX version of TCPDELAY + * .10 joh 112092 removed the requirement that VMS locking + * pairs reside at the same C bracket level + * .11 GeG 120992 support VMS/UCX * */ @@ -30,6 +35,9 @@ static char *os_depenhSccsId = "$Id$\t$Date$"; # ifndef _sys_time_h # include # endif +# ifndef _sys_errno_h +# include +# endif #elif defined(vxWorks) # ifndef INCvxWorksh # include @@ -78,17 +86,29 @@ static char *os_depenhSccsId = "$Id$\t$Date$"; /* independent of a particular operating system */ /************************************************************************/ #if defined(VMS) - /* provides for data structure mutal exclusive lock out */ - /* in the VMS AST environment. */ - /* note: the following must allways be used together */ -# define LOCK\ - {register long astenblwas;\ - astenblwas = sys$setast(FALSE); -# define UNLOCK\ - if(astenblwas == SS$_WASSET)sys$setast(TRUE);} + /* provides for data structure mutal exclusive lock out */ + /* in the VMS AST environment. */ + /* VMS locking recursion allowed */ +# define LOCK \ + { \ + register long astenblwas; \ + astenblwas = sys$setast(FALSE); \ + if(astenblwas == SS$_WASSET){ \ + ast_lock_count = 1; \ + } \ + else{ \ + ast_lock_count++; \ + } \ + } +# define UNLOCK \ + ast_lock_count--; \ + if(ast_lock_count <= 0){ \ + sys$setast(TRUE); \ + } # define LOCKEVENTS # define UNLOCKEVENTS # define EVENTLOCKTEST (post_msg_active!=0) +# define RECV_ACTIVE(PIIU) (piiu->active) #elif defined(vxWorks) # define VXTASKIDNONE 0 # define LOCK FASTLOCK(&client_lock); @@ -96,12 +116,14 @@ static char *os_depenhSccsId = "$Id$\t$Date$"; # define LOCKEVENTS {FASTLOCK(&event_lock); event_tid=(int)taskIdCurrent;} # define UNLOCKEVENTS {event_tid=VXTASKIDNONE; FASTUNLOCK(&event_lock);} # define EVENTLOCKTEST (FASTLOCKTEST(&event_lock)&&taskIdCurrent==event_tid) +# define RECV_ACTIVE(PIIU) (piiu->recv_tid == taskIdCurrent) #elif defined(UNIX) # define LOCK # define UNLOCK # define LOCKEVENTS # define UNLOCKEVENTS # define EVENTLOCKTEST (post_msg_active!=0) +# define RECV_ACTIVE(PIIU) (piiu->active) #else @@@@ dont compile in this case @@@@ #endif @@ -115,10 +137,13 @@ static char *os_depenhSccsId = "$Id$\t$Date$"; #if defined(VMS) -# ifdef WINTCP /* Wallangong */ +# if defined(WINTCP) /* Wallangong */ /* (the VAXC runtime lib has its own close */ # define socket_close(S) netclose(S) # define socket_ioctl(A,B,C) ioctl(A,B,C) +# elif defined(UCX) /* GeG 09-DEC-1992 */ +# define socket_close(S) close(S) +# define socket_ioctl(A,B,C) ioctl(A,B,C) # else # endif #elif defined(UNIX) @@ -196,7 +221,7 @@ static char *os_depenhSccsId = "$Id$\t$Date$"; }; #elif defined(vxWorks) # define SYSFREQ ((long) sysClkRateGet()) /* usually 60 Hz */ -# define TCPDELAY taskDelay(LOCALTICKS); +# define TCPDELAY taskDelay(ca_static->ca_local_ticks); # define time(A) (tickGet()/SYSFREQ) #elif defined(UNIX) # define SYSFREQ 1000000L /* 1 MHz */ @@ -209,7 +234,11 @@ static char *os_depenhSccsId = "$Id$\t$Date$"; { \ struct timeval dv; \ dv = tcpdelayval; \ - if(select(0,NULL,NULL,NULL,&dv)<0)abort(); \ + if(select(0,NULL,NULL,NULL,&dv)<0){ \ + if(MYERRNO != EINTR){ \ + ca_printf("TCPDELAY errno was %d\n", errno); \ + } \ + } \ } # ifdef CA_GLBLSOURCE struct timeval tcpdelayval = {0,LOCALTICKS}; diff --git a/src/ca/repeater.c b/src/ca/repeater.c index 6193dfb84..c15cf3dd7 100644 --- a/src/ca/repeater.c +++ b/src/ca/repeater.c @@ -54,6 +54,8 @@ * .05 072392 joh no longer needs to loop waiting for the timeout * to expire because of the change introduced * in .04 + * .06 120492 joh removed unnecessary includes + * .07 120992 joh now uses dll list routines * */ @@ -65,25 +67,22 @@ static char *sccsId = "$Id$\t$Date$"; # include # include # include -# include #elif defined(UNIX) # include # include # include # include -# include #elif defined(vxWorks) # include # include # include # include # include -# include #else @@@@ dont compile @@@@ #endif -#include +#include #include #include @@ -173,7 +172,7 @@ ca_repeater() struct one_client *pclient; struct one_client *pnxtclient; - lstInit(&client_list); + dllInit(&client_list); /* allocate a socket */ sock = socket( AF_INET, /* domain */ @@ -271,7 +270,7 @@ ca_repeater() malloc(sizeof *pclient); if(pclient){ pclient->from = from; - lstAdd(&client_list, pclient); + dllAdd(&client_list, pclient); #ifdef DEBUG ca_printf("Added %x %d\n", from.sin_port, size); #endif @@ -353,7 +352,7 @@ struct one_client *pclient; socket_close(sock); if(!present){ - lstDelete(&client_list, pclient); + dllDelete(&client_list, pclient); free(pclient); #ifdef DEBUG ca_printf("Deleted\n"); diff --git a/src/ca/service.c b/src/ca/service.c index 344d0dd04..bfb7da834 100644 --- a/src/ca/service.c +++ b/src/ca/service.c @@ -40,6 +40,12 @@ /* since it varies from os to os */ /* 040592 joh took out extra cac_send_msg() calls */ /* 072792 joh better messages */ +/* 110592 joh removed ptr dereference from test for valid */ +/* monitor handler function */ +/* 111792 joh reset retry delay for cast iiu when host */ +/* indicates the channel's address has changed */ +/* 120992 joh converted to dll list routines */ +/* 122192 joh now decrements the outstanding ack count */ /* */ /*_begin */ /************************************************************************/ @@ -124,11 +130,6 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) while (*pbufcnt >= sizeof(*hdrptr)) { -#ifdef DEBUG - ca_printf("CAC: bytes left %d, pending msgcnt %d\n", - *pbufcnt, - pndrecvcnt); -#endif /* byte swap the message up front */ t_available = (void *) hdrptr->m_available; @@ -148,6 +149,12 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) #endif msgcnt = sizeof(*hdrptr) + t_postsize; + +#ifdef DEBUG + ca_printf("CAC: bytes left %d, pending msgcnt %d\n", + *pbufcnt, + pndrecvcnt); +#endif if (*pbufcnt < msgcnt) { post_msg_active--; return OK; @@ -183,7 +190,7 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) * call handler, only if they did not clear the * chid in the interim */ - if (*monix->usr_func) { + if (monix->usr_func) { args.usr = monix->usr_arg; args.chid = monix->chan; args.type = t_type; @@ -195,10 +202,12 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) UNLOCKEVENTS; } LOCK; - lstDelete(&pend_read_list, monix); - lstAdd(&free_event_list, monix); + dllDelete(&pend_read_list, monix); + dllAdd(&free_event_list, monix); UNLOCK; + piiu->outstanding_ack_count--; + break; } case IOC_EVENT_ADD: @@ -218,10 +227,12 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) */ if (!t_postsize) { LOCK; - lstDelete(&monix->chan->eventq, monix); - lstAdd(&free_event_list, monix); + dllDelete(&monix->chan->eventq, monix); + dllAdd(&free_event_list, monix); UNLOCK; + piiu->outstanding_ack_count--; + break; } /* only call if not disabled */ @@ -313,10 +324,15 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) * This relies on the IOC_READ_BUILD msg * returning prior to the IOC_BUILD msg. */ - if (t_cmmd != IOC_READ_BUILD || - (chan->connection_func == NULL && - chan->state == cs_never_conn)) + if (t_cmmd == IOC_READ){ + piiu->outstanding_ack_count--; CLRPENDRECV(TRUE); + } + else if(chan->connection_func == NULL && + chan->state == cs_never_conn){ + CLRPENDRECV(TRUE); + } + break; } @@ -396,6 +412,7 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) break; } case IOC_READ_SYNC: + piiu->outstanding_ack_count--; piiu->read_seq++; break; @@ -423,17 +440,16 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) struct ioc_in_use *piiu = &iiu[chix->iocix]; LOCK; - lstDelete(&piiu->chidlist, chix); - lstAdd(&iiu[BROADCAST_IIU].chidlist, chix); + dllDelete(&piiu->chidlist, chix); + dllAdd(&iiu[BROADCAST_IIU].chidlist, chix); chix->iocix = BROADCAST_IIU; if (!piiu->chidlist.count) close_ioc(piiu); - /* * reset the delay to the next retry or keepalive */ - piiu->next_retry = CA_CURRENT_TIME; - piiu->nconn_tries = 0; + iiu[BROADCAST_IIU].next_retry = CA_CURRENT_TIME; + iiu[BROADCAST_IIU].nconn_tries = 0; manage_conn(TRUE); UNLOCK; @@ -457,12 +473,13 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) monix; monix = (evid) monix->node.next) if (monix->chan == chix) { - lstDelete(&pend_read_list, monix); - lstAdd(&free_event_list, monix); + dllDelete(&pend_read_list, monix); + dllAdd(&free_event_list, monix); } - lstConcat(&free_event_list, &chix->eventq); - lstDelete(&piiu->chidlist, chix); + dllConcat(&free_event_list, &chix->eventq); + dllDelete(&piiu->chidlist, chix); free(chix); + piiu->outstanding_ack_count--; if (!piiu->chidlist.count) close_ioc(piiu); UNLOCK; @@ -556,6 +573,9 @@ post_msg(hdrptr, pbufcnt, pnet_addr, piiu) } + if(piiu->outstanding_ack_count == 0){ + piiu->bytes_pushing_an_ack = 0; + } post_msg_active--; @@ -605,11 +625,11 @@ struct in_addr *pnet_addr; * The address changed (or was found for the first time) */ if(chan->iocix != BROADCAST_IIU) - ca_signal(ECA_NEWADDR, chan+1); + ca_signal(ECA_NEWADDR, (char *)(chan+1)); chpiiu = &iiu[chan->iocix]; - lstDelete(&chpiiu->chidlist, chan); + dllDelete(&chpiiu->chidlist, chan); chan->iocix = newiocix; - lstAdd(&iiu[newiocix].chidlist, chan); + dllAdd(&iiu[newiocix].chidlist, chan); } /* @@ -690,7 +710,7 @@ int lock; LOCK; } - while(pioe = (struct pending_io_event *) lstGet(&ioeventlist)){ + while(pioe = (struct pending_io_event *) dllGet(&ioeventlist)){ (*pioe->io_done_sub)(pioe->io_done_arg); free(pioe); } @@ -722,9 +742,9 @@ client_channel_exists(chan) for (piiu = iiu; piiu < pnext_iiu; piiu++) { /* - * lstFind returns the node number or ERROR + * dllFind returns the node number or ERROR */ - status = lstFind(&piiu->chidlist, chan); + status = dllFind(&piiu->chidlist, chan); if (status != ERROR) { return TRUE; } diff --git a/src/ca/test_event.c b/src/ca/test_event.c index 5e3291fc4..d8c442b44 100644 --- a/src/ca/test_event.c +++ b/src/ca/test_event.c @@ -14,7 +14,7 @@ * */ -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)test_event.c 1.6\t7/27/92"; /* System includes */ diff --git a/src/rsrv/camessage.c b/src/rsrv/camessage.c index 91c596b53..0d08afbe9 100644 --- a/src/rsrv/camessage.c +++ b/src/rsrv/camessage.c @@ -161,7 +161,7 @@ camessage(client, recv) RECORD_NAME(MPTOPADDR(mp))); UNLOCK_CLIENT(client); FASTLOCK(&rsrv_free_eventq_lck); - lstAdd(&rsrv_free_eventq, pevext); + lstAdd((LIST *)&rsrv_free_eventq, (NODE *)pevext); FASTUNLOCK(&rsrv_free_eventq_lck); break; } @@ -173,8 +173,8 @@ camessage(client, recv) * to be printed since it will not be found on * the list. */ - lstAdd( &((struct channel_in_use *)mp->m_pciu)->eventq, - pevext); + lstAdd( (LIST *)&((struct channel_in_use *)mp->m_pciu)->eventq, + (NODE *)pevext); /* * allways send it once at event add @@ -329,7 +329,7 @@ camessage(client, recv) if(status < 0){ free_client(client); logMsg("CAS: client timeout disconnect\n"); - exit(); + exit(0); } LOCK_CLIENT(client); lstAdd(&client->addrq, mp->m_pciu); @@ -401,7 +401,7 @@ struct client *client; taskSuspend(0); } FASTLOCK(&rsrv_free_eventq_lck); - lstAdd(&rsrv_free_eventq, pevext); + lstAdd((LIST *)&rsrv_free_eventq, (NODE *)pevext); FASTUNLOCK(&rsrv_free_eventq_lck); } @@ -418,11 +418,11 @@ struct client *client; *reply = *mp; END_MSG(client); - lstDelete(&client->addrq, pciu); + lstDelete((LIST *)&client->addrq, (NODE *)pciu); UNLOCK_CLIENT(client); FASTLOCK(&rsrv_free_addrq_lck); - lstAdd(&rsrv_free_addrq, pciu); + lstAdd((LIST *)&rsrv_free_addrq, (NODE *)pciu); FASTUNLOCK(&rsrv_free_addrq_lck); return; @@ -457,7 +457,7 @@ event_cancel_reply(mp, client) status = db_cancel_event(pevext + 1); if (status == ERROR) taskSuspend(0); - lstDelete(peventq, pevext); + lstDelete((LIST *)peventq, (NODE *)pevext); /* * send delete confirmed message @@ -475,7 +475,7 @@ event_cancel_reply(mp, client) UNLOCK_CLIENT(client); FASTLOCK(&rsrv_free_eventq_lck); - lstAdd(&rsrv_free_eventq, pevext); + lstAdd((LIST *)&rsrv_free_eventq, (NODE *)pevext); FASTUNLOCK(&rsrv_free_eventq_lck); return; @@ -655,7 +655,7 @@ build_reply(mp, client) LOCK_CLIENT(client); /* store the addr block in a Q so it can be deallocated */ - lstAdd(addrq, pchannel); + lstAdd((LIST *)addrq, (NODE *)pchannel); if (mp->m_cmmd == IOC_BUILD) { FAST short type = (mp + 1)->m_type; @@ -706,7 +706,7 @@ build_reply(mp, client) } search_reply = (struct extmsg *) ALLOC_MSG(client, 0); if (!search_reply) - taskSuspend(); + taskSuspend(0); *search_reply = *mp; search_reply->m_postsize = 0; diff --git a/src/rsrv/camsgtask.c b/src/rsrv/camsgtask.c index d29bf1c92..03afc8b6f 100644 --- a/src/rsrv/camsgtask.c +++ b/src/rsrv/camsgtask.c @@ -37,9 +37,13 @@ * if debug is on * .06 joh 021192 better diagnostics * .07 joh 031692 disconnect on bad message + * .08 joh 111892 set TCP buffer size to be synergistic + * with CA buffer size + * .09 joh 111992 moved the event tasks prioity down + * (added new arg to db_start_events()) */ -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)camsgtask.c 1.13\t11/20/92"; #include #include @@ -103,6 +107,36 @@ FAST int sock; return; } +#ifdef MATCHING_BUFFER_SIZES + /* + * set TCP buffer sizes to be synergistic + * with CA internal buffering + */ + i = MAX_MSG_SIZE; + status = setsockopt( + sock, + SOL_SOCKET, + SO_SNDBUF, + &i, + sizeof(i)); + if(status < 0){ + logMsg("CAS: SO_SNDBUF set failed\n"); + close(sock); + return; + } + i = MAX_MSG_SIZE; + status = setsockopt( + sock, + SOL_SOCKET, + SO_RCVBUF, + (char *)&i, + sizeof(i)); + if(status < 0){ + logMsg("CAS: SO_RCVBUF set failed\n"); + close(sock); + return; + } +#endif /* * performed in two steps purely for @@ -135,7 +169,7 @@ FAST int sock; } LOCK_CLIENTQ; - lstAdd(&clientQ, client); + lstAdd((LIST *)&clientQ, (NODE *)client); UNLOCK_CLIENTQ; client->evuser = (struct event_user *) db_init_events(); @@ -148,7 +182,8 @@ FAST int sock; client->evuser, CA_EVENT_NAME, NULL, - NULL); + NULL, + 1); /* one priority notch lower */ if (status == ERROR) { logMsg("CAS: unable to start the event facility\n"); free_client(client); diff --git a/src/rsrv/caserverio.c b/src/rsrv/caserverio.c index b6003cab3..4e5f36f72 100644 --- a/src/rsrv/caserverio.c +++ b/src/rsrv/caserverio.c @@ -35,7 +35,7 @@ * .06 joh 031992 improved diagnostics */ -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)caserverio.c 1.10\t7/28/92"; #include #include diff --git a/src/rsrv/caservertask.c b/src/rsrv/caservertask.c index f1e41e8b5..f18602f7c 100644 --- a/src/rsrv/caservertask.c +++ b/src/rsrv/caservertask.c @@ -42,7 +42,7 @@ * .10 joh 022592 print more statistics in client_stat() */ -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)caservertask.c 1.13\t7/28/92"; #include #include @@ -54,6 +54,9 @@ static char *sccsId = "$Id$\t$Date$"; #include #include +LOCAL int terminate_one_client(); +LOCAL void log_one_client(); + /* * @@ -114,7 +117,7 @@ req_server() CA_CLIENT_PRI, CA_CLIENT_OPT, CA_CLIENT_STACK, - camsgtask, + (FUNCPTR) camsgtask, i); if (status == ERROR) { logMsg("CAS: task creation failed\n"); @@ -140,11 +143,11 @@ register struct client *client; /* remove it from the list of clients */ /* list delete returns no status */ LOCK_CLIENTQ; - lstDelete(&clientQ, client); + lstDelete((LIST *)&clientQ, (NODE *)client); UNLOCK_CLIENTQ; terminate_one_client(client); LOCK_CLIENTQ; - lstAdd(&rsrv_free_clientQ, client); + lstAdd((LIST *)&rsrv_free_clientQ, (NODE *)client); UNLOCK_CLIENTQ; } else { LOCK_CLIENTQ; @@ -206,13 +209,13 @@ register struct client *client; pciu = (struct channel_in_use *) & client->addrq; while (pciu = (struct channel_in_use *) pciu->node.next){ - while (pevext = (struct event_ext *) lstGet(&pciu->eventq)) { + while (pevext = (struct event_ext *) lstGet((LIST *)&pciu->eventq)) { status = db_cancel_event(pevext + 1); if (status == ERROR) taskSuspend(0); FASTLOCK(&rsrv_free_eventq_lck); - lstAdd(&rsrv_free_eventq, pevext); + lstAdd((LIST *)&rsrv_free_eventq, (NODE *)pevext); FASTUNLOCK(&rsrv_free_eventq_lck); } } @@ -252,12 +255,12 @@ client_stat() LOCK_CLIENTQ; - client = (struct client *) lstNext(&clientQ); + client = (struct client *) lstNext((NODE *)&clientQ); while (client) { log_one_client(client); - client = (struct client *) lstNext(client); + client = (struct client *) lstNext((NODE *)client); } UNLOCK_CLIENTQ; @@ -287,7 +290,7 @@ client_stat() * log_one_client() * */ -static void +LOCAL void log_one_client(client) struct client *client; { @@ -330,8 +333,8 @@ struct client *client; bytes_reserved += sizeof(struct channel_in_use); bytes_reserved += (sizeof(struct event_ext)+db_sizeof_event_block())* - lstCount(&pciu->eventq); - pciu = (struct channel_in_use *) lstNext(pciu); + lstCount((LIST *)&pciu->eventq); + pciu = (struct channel_in_use *) lstNext((NODE *)pciu); } @@ -352,7 +355,7 @@ struct client *client; printf( "\t%s(%d) ", pciu->addr.precord, pciu->eventq.count); - pciu = (struct channel_in_use *) lstNext(pciu); + pciu = (struct channel_in_use *) lstNext((NODE *)pciu); } printf("\n"); diff --git a/src/rsrv/cast_server.c b/src/rsrv/cast_server.c index dca3aa5e5..5912b8082 100644 --- a/src/rsrv/cast_server.c +++ b/src/rsrv/cast_server.c @@ -56,7 +56,7 @@ * pend which could lock up the cast server. */ -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)cast_server.c 1.13\t7/28/92"; #include #include @@ -85,7 +85,7 @@ cast_server() { struct sockaddr_in sin; FAST int status; - int count; + int count=0; struct sockaddr_in new_recv_addr; int recv_addr_size; unsigned nchars; @@ -128,7 +128,7 @@ cast_server() CA_ONLINE_PRI, CA_ONLINE_OPT, CA_ONLINE_STACK, - rsrv_online_notify_task); + (FUNCPTR)rsrv_online_notify_task); if(status<0){ logMsg("CAS: couldnt start up online notify task\n"); printErrno(errnoGet ()); @@ -276,9 +276,9 @@ struct client *pclient; } if (delay > timeout) { - lstDelete(&pclient->addrq, pciu); + lstDelete((LIST *)&pclient->addrq, (NODE *)pciu); FASTLOCK(&rsrv_free_addrq_lck); - lstAdd(&rsrv_free_addrq, pciu); + lstAdd((LIST *)&rsrv_free_addrq, (NODE *)pciu); FASTUNLOCK(&rsrv_free_addrq_lck); ndelete++; maxdelay = max(delay, maxdelay); diff --git a/src/rsrv/globalsource.c b/src/rsrv/globalsource.c index 8b3fb92c2..b9dcd9a7b 100644 --- a/src/rsrv/globalsource.c +++ b/src/rsrv/globalsource.c @@ -30,7 +30,7 @@ */ #define GLBLSOURCE -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)globalsource.c 1.5\t7/28/92"; #include #include diff --git a/src/rsrv/online_notify.c b/src/rsrv/online_notify.c index 055e5ded6..3a4ac09ea 100644 --- a/src/rsrv/online_notify.c +++ b/src/rsrv/online_notify.c @@ -49,7 +49,7 @@ static char *sccsId = "$Id$\t$Date$"; #include #include -#define abort taskSuspend +#define abort(A) taskSuspend(0) /* @@ -91,7 +91,7 @@ void rsrv_online_notify_task() status = local_addr(sock, &lcl); if(status<0){ logMsg("CAS: online notify: Network interface unavailable\n"); - abort(); + abort(0); } status = setsockopt( sock, @@ -133,8 +133,11 @@ void rsrv_online_notify_task() 0, &send_addr, sizeof send_addr); - if(status != sizeof msg) - abort(); + if(status != sizeof msg){ + logMsg( "%s: Socket send error was %d\n", + __FILE__, + errnoGet(taskIdSelf()) ); + } taskDelay(delay); delay = min(delay << 1, maxdelay); diff --git a/src/rsrv/rsrv_init.c b/src/rsrv/rsrv_init.c index 4b8f049e0..fb938dea7 100644 --- a/src/rsrv/rsrv_init.c +++ b/src/rsrv/rsrv_init.c @@ -29,7 +29,7 @@ * ----------------- */ -static char *sccsId = "$Id$\t$Date$"; +static char *sccsId = "@(#)rsrv_init.c 1.7\t7/28/92"; #include #include diff --git a/src/rsrv/server.h b/src/rsrv/server.h index 8425c8044..9262c67c9 100644 --- a/src/rsrv/server.h +++ b/src/rsrv/server.h @@ -42,7 +42,7 @@ #ifndef INCLserverh #define INCLserverh -static char *serverhSccsId = "$Id$\t$Date$"; +static char *serverhSccsId = "@(#)server.h 1.10\t7/28/92"; #ifndef INCLfast_lockh #include