diff --git a/src/ca/gsd_sync_subr.c b/src/ca/gsd_sync_subr.c deleted file mode 100644 index 5cb327408..000000000 --- a/src/ca/gsd_sync_subr.c +++ /dev/null @@ -1,1170 +0,0 @@ -/* -*************************************************** -* File: /home/lando/slentz/sync/unix_gsd_sync.c -* Modifications: -* 09/18/90 ges creation -* 09/21/90 ges desk check -* 10/15/90 ges add gsd_copy_buffer routine -* 10/17/90 ges clean-up and add to documentation -* add timeout parameter to gsd_sync_read -* 11/01/90 ges add gsd_sync_clear function -* 11/05/90 ges add linked list event data approach -* 11/16/90 ges make special UNIX version for OPI -* 11/20/90 ges make gsd_sync_init return VOID * for consistency -* between UNIX and VxWorks versions -* 11/26/90 ges use ca_build_and_connect in gsd_sync_init -* 11/27/90 ges add NULL ptr return 0 to gsd_tss_eq -* add NULL ptr return 0 to gsd_tss_gtr -* change from (gsd_tss_gtr) to (gsd_tss_gtr || -* gsd_tss_eq) in gsd_findlargest_ts -* 12/14/90 ges add events at gsd_sync_read instead of gsd_sync_init -* return most recent chan data if chan failed to -* produce data with the associated time stamp -* 09/03/91 joh fixed includes for V5 vxWorks -* 06/26/92 joh now uses ca_printf instead of printf -* -* -* Compile: -* for Unix: -* compile: -* make -* execute: -* unix_gsd_sync -*------------------------------------------------- -* Usage: -* 1) A single initial call to gsd_sync_init must be made before -* any additional calls to gsd_sync_read". -* 2) Calls to UNIX version of "gsd_sync_read": -* 1) returns 1 if done, either timed out or has valid -* synchronous data on all channels of interest -* returns 0 if not done, allowing the calling program -* to continue polling for done by repeated -* calls to gsd_sync_read -* 2) with NEXTSET_SYNC_DATA: Pushes any currently saved valid -* event data down to the "previous" level store. -* At invocation, time stamp data monitors are established -* for each channel named. -* All event data is then received and stored in sequence -* until either: -* 1) event data containg identical time stamps has been -* received from all channels named (this time stamp -* is selected to be associated with this sync -* data call) or -* 2) time out occurs (in this case the most recent -* time stamp of all the collected event data -* is selected as the time stamp associated with -* this sync data call) -* Data that has the associated time stamp -* will be marked as valid and will be copied to the -* synchronous data buffers. If a channel has no data with -* the associated time stamp, then its most recent received -* data will be copied to the synchronous data buffers and -* will be marked not valid. -* 3) with PREVIOUS_SYNC_DATA: yields the collected and -* saved data that currently reside in the "previous" -* level store. -* 3) Interpretation of flags: -* 1) gsd_sync_data.svalid: is 1 if new sync event data has come in -* over that channel during its synchronous read window. -* The pointer gsd_sync_data.pSdata points to the -* DBR_TIME_XXXX structure containing this new data. -* : is 0 if no new synchronous -* event data has come in -* over that channel during its synchronous read window. -* The pointer gsd_sync_data.pSdata points the the -* DBR_TIME_XXXX structure and will contain the remaining -* old residual data unchanged from the most recent -* successful synchronous event. -* 2) gsd_sync_data.pSdata: is 0 (i.e. NULL) if that channel -* has never established network connection. If NULL then -* no DBR_TIME_XXXX data is yet available. -*************************************************** -*/ - -static char *sccsId = "@(#)gsd_sync_subr.c 1.8\t11/5/92"; - -#if defined(UNIX) -# include -# include -# include -# include -#else -# if defined(vxWorks) -# define abort(A) taskSuspend(taskIdSelf()) -# ifdef V5vxWorks -# include -# else -# include -# endif -# if 0 /* needed ?? */ -# include -# include -# include -# endif -# else - @@@@ dont compile in this case @@@@ -# endif -#endif - -#include -#include - - - -/* -*-------------------------------------------- -* Function prototypes -*-------------------------------------------- -*/ -VOID gsd_fd_register(); -VOID gsd_ca_service(); - -VOID gsd_ca_task_initialize(); -VOID gsd_ca_pend_event(); -VOID *gsd_sync_init(); -VOID gsd_connevent_handler(); -VOID gsd_event_handler(); -int gsd_sync_read(); -TS_STAMP *gsd_complete_set(); -VOID gsd_copy_buffer(); -int gsd_timeout(); -VOID gsd_sync_clear(); -int gsd_tss_within_delta(); -int gsd_tss_eq(); -int gsd_tss_gtr(); -TS_STAMP *gsd_findlargest_ts(); -VOID gsd_freeevent_mem(); -VOID gsd_syncset_findcopy(); -TS_STAMP *gsd_get_ts(); - - -/*-------------------------------------------*/ - -struct gsd_sync_linked { - struct gsd_sync_linked *pNstruct; /* ptr to next gsd_sync_linked struct */ - VOID *pNdata; /* ptr to event TBR_TIME_xxxx data */ -}; - -struct gsd_sync_ctrl { - struct gsd_sync_data *pDstruct; /* ptr to assoc gsd_sync_data struc */ - int nvalid; /* next data's valid flag */ - int avalid; /* already data's valid flag */ - VOID *pNdata; /* ptr to next data set */ - VOID *pAdata; /* ptr to immediately previous (already) data set */ - struct gsd_sync_linked *pNstruct; /* ptr to head linked data sets */ - int en_event; /* enable the storage of event data */ - evid event_id; /* event id storage for this channel */ -}; - -struct gsd_sync_compctrl { - struct timeval start_time; /* sys time store at initial call */ - struct gsd_sync_ctrl *pCtrl; /* ptr to gsd_sync_ctrl array */ -}; - -/*---------------------------------------------*/ -#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 */ - - - - -/* test only !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ -/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ -/* -*------------------------------------------------------ -* For stand-alone operation remove the comments that bracket this -* mainline driver and call: -* main() -*------------------------------------------------------ -*/ -#define CHAN_COUNT 4 /* 4 channels for this example test code */ -#define SYNC_TIMEOUT 1.0 /* timeout for data reception in float secs */ - -struct gsd_sync_data sync_data_array[CHAN_COUNT]; -struct gsd_sync_data *pSync_data_array = &sync_data_array[0]; -/* -main() -{ - VOID *pfdctx = NULL; - struct gsd_sync_compctrl *pSync_compctrl; - struct gsd_sync_ctrl *pSync_ctrl; - int i; - - sync_data_array[0].pName = "IOC21:CALC:S00:00"; - sync_data_array[1].pName = "IOC21:CALC:S00:01"; - sync_data_array[2].pName = "BSD_41N:00:00"; - sync_data_array[3].pName = "BSD_21:00:00"; - - SEVCHK(ca_task_initialize(), - "main: C.A. initialize failure.\n"); - pSync_compctrl = (struct gsd_sync_compctrl *) - gsd_sync_init(pSync_data_array, CHAN_COUNT, &pfdctx, NULL); - if(NULL == pSync_compctrl) { - ca_printf("unable to continue, gsd_sync_init failed\n"); - return 1; - } - pSync_ctrl = pSync_compctrl->pCtrl; - - - gsd_sync_read(PREVIOUS_SYNC_DATA, pSync_compctrl, CHAN_COUNT, &pfdctx, - SYNC_TIMEOUT); - ca_printf("result of sync_read(PREVIOUS_SYNC_DATA)\n"); - for (i = 0; i < CHAN_COUNT; ++i) { - ca_printf("%s valid = %d ptr = %d \n", - (pSync_ctrl->pDstruct)->pName, (pSync_ctrl->pDstruct)->svalid, - (pSync_ctrl->pDstruct)->pSdata); - if((pSync_ctrl->pDstruct)->pSdata) { - ca_printf("ts sec = %ld ts nsec = %ld value = %f\n", - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.secPastEpoch, - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.nsec, - ((struct dbr_time_float*) - ((pSync_ctrl->pDstruct)->pSdata))->value); - } - ++pSync_ctrl; - } - pSync_ctrl = pSync_compctrl->pCtrl; - ca_printf("\n"); - - - while(!gsd_sync_read(NEXTSET_SYNC_DATA, pSync_compctrl, CHAN_COUNT, &pfdctx, - SYNC_TIMEOUT)) { - ; - } - ca_printf("result of sync_read(NEXTSET_SYNC_DATA)\n"); - for (i = 0; i < CHAN_COUNT; ++i) { - ca_printf("%s valid = %d ptr = %d \n", - (pSync_ctrl->pDstruct)->pName, (pSync_ctrl->pDstruct)->svalid, - (pSync_ctrl->pDstruct)->pSdata); - if((pSync_ctrl->pDstruct)->pSdata) { - ca_printf("ts sec = %ld ts nsec = %ld value = %f\n", - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.secPastEpoch, - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.nsec, - ((struct dbr_time_float*) - ((pSync_ctrl->pDstruct)->pSdata))->value); - } - ++pSync_ctrl; - } - pSync_ctrl = pSync_compctrl->pCtrl; - ca_printf("\n"); - - - gsd_sync_read(PREVIOUS_SYNC_DATA, pSync_compctrl, CHAN_COUNT, &pfdctx, - SYNC_TIMEOUT); - ca_printf("result of sync_read(PREVIOUS_SYNC_DATA)\n"); - for (i = 0; i < CHAN_COUNT; ++i) { - ca_printf("%s valid = %d ptr = %d \n", - (pSync_ctrl->pDstruct)->pName, (pSync_ctrl->pDstruct)->svalid, - (pSync_ctrl->pDstruct)->pSdata); - if((pSync_ctrl->pDstruct)->pSdata) { - ca_printf("ts sec = %ld ts nsec = %ld value = %f\n", - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.secPastEpoch, - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.nsec, - ((struct dbr_time_float*) - ((pSync_ctrl->pDstruct)->pSdata))->value); - } - ++pSync_ctrl; - } - pSync_ctrl = pSync_compctrl->pCtrl; - ca_printf("\n"); - - - while(!gsd_sync_read(NEXTSET_SYNC_DATA, pSync_compctrl, CHAN_COUNT, &pfdctx, - SYNC_TIMEOUT)) { - ; - } - ca_printf("result of sync_read(NEXTSET_SYNC_DATA)\n"); - for (i = 0; i < CHAN_COUNT; ++i) { - ca_printf("%s valid = %d ptr = %d \n", - (pSync_ctrl->pDstruct)->pName, (pSync_ctrl->pDstruct)->svalid, - (pSync_ctrl->pDstruct)->pSdata); - if((pSync_ctrl->pDstruct)->pSdata) { - ca_printf("ts sec = %ld ts nsec = %ld value = %f\n", - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.secPastEpoch, - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.nsec, - ((struct dbr_time_float*) - ((pSync_ctrl->pDstruct)->pSdata))->value); - } - ++pSync_ctrl; - } - pSync_ctrl = pSync_compctrl->pCtrl; - ca_printf("\n"); - - - gsd_sync_read(PREVIOUS_SYNC_DATA, pSync_compctrl, CHAN_COUNT, &pfdctx, - SYNC_TIMEOUT); - ca_printf("result of sync_read(PREVIOUS_SYNC_DATA)\n"); - for (i = 0; i < CHAN_COUNT; ++i) { - ca_printf("%s valid = %d ptr = %d \n", - (pSync_ctrl->pDstruct)->pName, (pSync_ctrl->pDstruct)->svalid, - (pSync_ctrl->pDstruct)->pSdata); - if((pSync_ctrl->pDstruct)->pSdata) { - ca_printf("ts sec = %ld ts nsec = %ld value = %f\n", - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.secPastEpoch, - ((struct dbr_time_float *) - ((pSync_ctrl->pDstruct)->pSdata))->stamp.nsec, - ((struct dbr_time_float*) - ((pSync_ctrl->pDstruct)->pSdata))->value); - } - ++pSync_ctrl; - } - pSync_ctrl = pSync_compctrl->pCtrl; - ca_printf("\n"); - - - gsd_sync_clear(pSync_compctrl, CHAN_COUNT); - ca_printf("End of test and demo.\n\n"); - - return 0; -} -*/ -/* end test!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ -/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ - -/* -******************************************************* -* Description: -* 1) Entry with pSync containing the base address of the array of -* gsd_sync_data structures (chan_count of these) -* 2) Alloc memory for a composite control structure instance and -* an array of gsd_sync_ctrl structures, -* one for each gsd_sync_data structure -* 3) Establish a connection event handler -* 4) For each gsd_sync_ctrl structure -* 1) init pCtrl->Dstruct to point to its associated -* gsd_sync_data structure -* 2) init to NULL the pSdata ptr in associated pSync -* (this is used as a flag to indicate if channel has -* ever been up in function "gsd_connevent_handler") -* 3) broadcast chan access search -* 5) Flush i/o for channel access -* 6) Returns pCompctrl, the address of the composite control struct -* which must be used for any subsequent gsd_sync_read(flag,pCtrl, -* chan_count) calls -* pCompctrl == NULL: error, unable to allocate memory. -* pCompctrl != NULL: success, normal execution. -******************************************************* -*/ - - -VOID *gsd_sync_init(pSync, chan_count, pfdctx, pMac_pairs) -struct gsd_sync_data *pSync; -unsigned int chan_count; -VOID **pfdctx; -char *pMac_pairs[]; -{ - int i; - struct gsd_sync_compctrl *pCompctrl; - struct gsd_sync_ctrl *pCtrl; - - if(*pfdctx == NULL) { - gsd_ca_task_initialize(pfdctx); - } - - pCompctrl = (struct gsd_sync_compctrl *) - calloc(1, sizeof(struct gsd_sync_compctrl)); - if(pCompctrl == NULL) { - ca_printf("gsd_sync_init: mem alloc failed\n"); - return NULL; - } - - pCtrl = (struct gsd_sync_ctrl *) calloc(chan_count, sizeof(struct gsd_sync_ctrl)); - if(pCtrl == NULL) { - ca_printf("gsd_sync_init: mem alloc failed\n"); - free(pCompctrl); - return NULL; - } - pCompctrl->pCtrl = pCtrl; - - for(i = 0; i < chan_count; i++) { - pCtrl->pDstruct = pSync; - pSync->pSdata = NULL; - if(strlen(pSync->pName) > 0){ - char name_str[db_name_dim]; - if(pMac_pairs != NULL){ - gsdl_main_macro(name_str, pSync->pName, pMac_pairs, db_name_dim); - strcpy(pSync->pName, name_str); - } -/* ca_printf("new_str = %s\n", pSync->pName);*/ - SEVCHK(ca_build_and_connect(pSync->pName, TYPENOTCONN, 0, - &(pSync->pChid), (VOID *) NULL, - gsd_connevent_handler, (VOID *) pCtrl), - "gs_sync_init: broadcast search failed\n"); - ca_flush_io(); - } - ++pSync; - ++pCtrl; - } - - gsd_ca_pend_event(pfdctx); - return (VOID *) pCompctrl; -} -/* -**************************************************** -* Description: -* 1) If first time channel connect has been up (i.e. no valid -* memory address for pSdata) then -* 1) Allocate memory for the sync data and fill pSdata -* with its address. If fail, return. (no monitor started) -* 2) Allocate memory for the next data. If fail, -* free memory gotten so far, and return. -* (no monitor started) -* 3) Allocate memory for the already data. If fail, -* free memory gotten so far, and return. -* (no monitor started) -* 4) Start event monitor on channel -* 5) Flush i/o for channel access -***************************************************** -*/ -VOID gsd_connevent_handler(args) -struct connection_handler_args args; -{ - struct gsd_sync_ctrl *pCtrl = ca_puser(args.chid); - struct gsd_sync_data *pSync = pCtrl->pDstruct; - - if(args.op == CA_OP_CONN_UP) { - if(pSync->pSdata == NULL) { - - pSync->pSdata = (VOID *) calloc(1, dbr_size_n( - dbf_type_to_DBR_TIME(ca_field_type(args.chid)), - ca_element_count(args.chid))); - if(pSync->pSdata == NULL) { - ca_printf("gsd_connevent_handler: mem alloc fail\n"); - return; - } - pCtrl->pNdata = (VOID *) calloc(1, dbr_size_n( - dbf_type_to_DBR_TIME(ca_field_type(args.chid)), - ca_element_count(args.chid))); - if(pCtrl->pNdata == NULL) { - free(pSync->pSdata); - pSync->pSdata = NULL; - ca_printf("gsd_connevent_handler: mem alloc fail\n"); - return; - } - pCtrl->pAdata = (VOID *) calloc(1, dbr_size_n( - dbf_type_to_DBR_TIME(ca_field_type(args.chid)), - ca_element_count(args.chid))); - if(pCtrl->pAdata == NULL) { - free(pSync->pSdata); - pSync->pSdata = NULL; - free(pCtrl->pNdata); - pCtrl->pNdata = NULL; - ca_printf("gsd_connevent_handler: mem alloc fail\n"); - return; - } - - pSync->time_type = dbf_type_to_DBR_TIME( - ca_field_type(pSync->pChid)); - pSync->count = ca_element_count(pSync->pChid); - -/* - ca_printf("%s type = %d count = %d\n", - pSync->pName, pSync->time_type, pSync->count); -*/ - } - } - return; -} -/* -*********************************************************** -* Description: -* 1) if (event is enabled) then -* 1) if (event is the 1st for this channel (pN == NULL)) then -* 1) alloc mem for a gsd_sync_linked structure and -* place its addr into the pN ptr -* else -* 1) traverse linked list until pN points to last -* gsd_sync_linked structure -* 2) allocate memory for a new gsd_sync_linked -* structure and append it to end of linked list -* 3) Update pN to point to this new last structure -* 2) allocate memory to hold the data -* 3) copy the data into this buffer -*********************************************************** -*/ -VOID gsd_event_handler(args) -struct event_handler_args args; -{ - struct gsd_sync_ctrl *pCtrl = args.usr; - struct gsd_sync_linked *pN = pCtrl->pNstruct; - struct gsd_sync_linked *pAlloc_linked; - VOID *pAlloc_data; - - if(pCtrl->en_event) { - pAlloc_linked = (struct gsd_sync_linked *) calloc(1, - sizeof(struct gsd_sync_linked)); - pAlloc_data = (VOID *) calloc(1, dbr_size_n(args.type,args.count)); - if((NULL == pAlloc_linked) || (NULL == pAlloc_data)) { - ca_printf("gsd_event_handler: mem alloc failed.\n"); - /* clean-up unused memory */ - if(pAlloc_linked != NULL) free(pAlloc_linked); - if(pAlloc_data != NULL) free(pAlloc_data); - return; - } - - if(pN == NULL) { - pCtrl->pNstruct = pAlloc_linked; - pN = pAlloc_linked; - } - else { - while(pN->pNstruct) pN = pN->pNstruct; - pN->pNstruct = pAlloc_linked; - pN = pN->pNstruct; - } - - pN->pNdata = pAlloc_data; - - gsd_copy_buffer(args.dbr, pN->pNdata, dbr_size_n(args.type, - args.count)); - -/* - ca_printf("%s ts sec = %ld ts nsec = %ld value = %f\n", - (pCtrl->pDstruct)->pName, - ((struct dbr_time_float *) (pN->pNdata))->stamp.secPastEpoch, - ((struct dbr_time_float *) (pN->pNdata))->stamp.nsec, - ((struct dbr_time_float *) (pN->pNdata))->value); -*/ - - } - - return; -} - -/* -***************************************************** -* Description: -* 1) if (PREVIOUS_SYNC_DATA) then -* 1) for each channel -* 1) if channel has ever been up then -* 1) copy already data to sync data -* 2) copy already valid flag to sync valid flag -* else -* 1) place NULL in sync data ptr -* 2) clear sync valid flag to zero -* 2) if (NEXTSET_SYNC_DATA) then -* 1) if first call indicated by 0 start time then -* 1) for each channel -* 1) if channel has ever been up then -* 1) copy old next data to already level data -* copy old next valid flags to already -* level valid flags -* 2) clear next valid flags -* 3) enable capture of monitor data until -* a full set is acquired or timeout -* 4) add monitor event -* 2) fill with system time -* 3) return 0 indicating not done -* 2) if complete set received or timed out then -* 1) clear start time to 0 to prepare for -* possible next call -* 2) for each channel -* 1) disable further capture of data -* 2) clear monitor event -* 3) copy chosen time stamp data to next level -* (if no data received, don't over copy to -* next level, but clear valid flag on next levl -* 4) for each channel -* 1) if channel has ever been up then -* 1) copy next level data to sync data -* 2) copy next level valid flag to -* sync valid flag -* 3) free memory of linked list and -* its associated data buffer -* else -* 1) place NULL in sync data ptr -* 2) set sync valid flag to zero -* 5) return 1 indicating done -* 3) return 0 indicating not done -* 3) return 1 indicating done with unknown request -***************************************************** -*/ - - -int gsd_sync_read(flag, pCompctrl,chan_count, pfdctx, timeout_secs) -char flag; -struct gsd_sync_compctrl *pCompctrl; -unsigned int chan_count; -VOID *pfdctx; -float timeout_secs; -{ - struct gsd_sync_ctrl *pCtrl = pCompctrl->pCtrl; - TS_STAMP *pTs; - struct timezone zone; - int i; - - if(NULL == pCompctrl) { - ca_printf("gsd_sync_read: error NULL arg for pCompctrl\n"); - return 0; - } - - if(flag == PREVIOUS_SYNC_DATA) { - for (i = 0; i < chan_count; i++) { - if(pCtrl->pAdata != NULL) { - gsd_copy_buffer(pCtrl->pAdata, - (pCtrl->pDstruct)->pSdata, - dbr_size_n((pCtrl->pDstruct)->time_type, - (pCtrl->pDstruct)->count)); - (pCtrl->pDstruct)->svalid = pCtrl->avalid; - } - else { - (pCtrl->pDstruct)->pSdata = NULL; - (pCtrl->pDstruct)->svalid = 0; - } - ++pCtrl; - } - return 1; /* done with PREVIOUS_SYNC_DATA request */ - } - - if(flag == NEXTSET_SYNC_DATA) { - if(((pCompctrl->start_time).tv_sec == 0) && - ((pCompctrl->start_time).tv_usec == 0)) { - for (i = 0; i < chan_count; i++) { - if(pCtrl->pNdata != NULL) { - gsd_copy_buffer(pCtrl->pNdata, - pCtrl->pAdata, - dbr_size_n((pCtrl->pDstruct)->time_type, - (pCtrl->pDstruct)->count)); - pCtrl->avalid = pCtrl->nvalid; - pCtrl->nvalid = 0; - pCtrl->en_event = 1; - - SEVCHK(ca_add_array_event( - (pCtrl->pDstruct)->time_type, - (pCtrl->pDstruct)->count, - (pCtrl->pDstruct)->pChid, gsd_event_handler, - pCtrl, (float) 0, (float) 0, (float) 0, - &(pCtrl->event_id)), - "gsd_connevent_handler: add event failed\n"); - } - ++pCtrl; - } - ca_flush_io(); - gettimeofday(&(pCompctrl->start_time), &zone); - return 0; /* not done */ - } - - if((pTs = gsd_complete_set(pCompctrl->pCtrl, chan_count)) || - (gsd_timeout(pCompctrl, timeout_secs, pfdctx))) { - - (pCompctrl->start_time).tv_sec = 0; - (pCompctrl->start_time).tv_usec = 0; - - pCtrl = pCompctrl->pCtrl; - for (i = 0; i < chan_count; ++i) { - pCtrl->en_event = 0; - if(pCtrl->event_id) ca_clear_event(pCtrl->event_id); - ++pCtrl; - } - ca_flush_io(); - - pCtrl = pCompctrl->pCtrl; - - if(pTs != NULL) { -/* - ca_printf("got sync data set\n"); -*/ - gsd_syncset_findcopy(pCtrl, - chan_count, pTs); - } - else { -/* - ca_printf("settle for last \n"); -*/ - pTs = gsd_findlargest_ts(pCtrl, - chan_count); - gsd_syncset_findcopy(pCtrl, chan_count, - pTs); - } - - for(i = 0; i < chan_count; i++) { - if(pCtrl->pNdata != NULL) { - gsd_copy_buffer(pCtrl->pNdata, - (pCtrl->pDstruct)->pSdata, - dbr_size_n((pCtrl->pDstruct)->time_type, - (pCtrl->pDstruct)->count)); - (pCtrl->pDstruct)->svalid = pCtrl->nvalid; - gsd_freeevent_mem(pCtrl); - } - else { - (pCtrl->pDstruct)->pSdata = NULL; - (pCtrl->pDstruct)->svalid = 0; - } - ++pCtrl; - } - return 1; /* done with NEXT_SYNC_DATA request, */ - /* either fullset or timeout */ - } - - return 0; /* not done with NEXT_SYNC_DATA request */ - } - return 1; /* done, unknown request */ -} -/* -************************************************ -* Description: -* 1) If a set of identically time stamped data is found in -* each channel of interest then -* 1) return a ptr to one of the identical time stamps -* 2) Otherwise return NULL ptr -************************************************ -*/ -TS_STAMP *gsd_complete_set(pCtrl, chan_count) -struct gsd_sync_ctrl *pCtrl; -unsigned int chan_count; -{ - struct gsd_sync_linked *pNfirst_chan = pCtrl->pNstruct; - struct gsd_sync_linked *pNchan = NULL; - TS_STAMP *pEqual = NULL; - - int i; - struct gsd_sync_ctrl *pCtrl_copy; - - while(pNfirst_chan != NULL) { /* for every data rec receiv in 1st chn*/ - pCtrl_copy = pCtrl; - for(i = 0; i < chan_count; ++i) { /* for every channel in chan array */ - pEqual = NULL; - - pNchan = pCtrl_copy->pNstruct; - while(pNchan != NULL) { - /* for every data record received by this channel */ - /* may want to use gsd_tss_within_delta instead of eq */ - if(gsd_tss_eq( - gsd_get_ts((pCtrl->pDstruct)->time_type, - pNfirst_chan->pNdata), - gsd_get_ts((pCtrl_copy->pDstruct)->time_type, - pNchan->pNdata))) { - pEqual = gsd_get_ts( - (pCtrl->pDstruct)->time_type, - pNfirst_chan->pNdata); - break; - } - pNchan = pNchan->pNstruct; - } - if(NULL == pEqual) break; - /* no ts match in this chan, exit the for, */ - /* and try next 1st channel time stamp */ - pCtrl_copy++; - } - if(pEqual != NULL) return pEqual; /* success */ - pNfirst_chan = pNfirst_chan->pNstruct; - /* try next data record of 1st channel */ - } - return NULL; /* failed, returning NULL ptr */ -} -/* -*************************** -* Description: -* 1) returns ptr to the time stamp structure within the data buffer of -* types DBR_TIME_xxxx (an accessor routine) -****************************** -*/ -TS_STAMP *gsd_get_ts(time_type, pNdata) -int time_type; -void *pNdata; -{ - switch(time_type) { - case DBR_TIME_STRING: - return &(((struct dbr_time_string *) pNdata)->stamp); - case DBR_TIME_SHORT: - return &(((struct dbr_time_short *) pNdata)->stamp); - case DBR_TIME_FLOAT: - return &(((struct dbr_time_float *) pNdata)->stamp); - case DBR_TIME_ENUM: - return &(((struct dbr_time_enum *) pNdata)->stamp); - case DBR_TIME_CHAR: - return &(((struct dbr_time_char *) pNdata)->stamp); - case DBR_TIME_LONG: - return &(((struct dbr_time_long *) pNdata)->stamp); - case DBR_TIME_DOUBLE: - return &(((struct dbr_time_double *) pNdata)->stamp); - default: - return NULL; - } -} - -/* -************************************************ -* Description: -* 1) returns ptr to the largest time stamp found in -* all of the channel data collected. If no data then -* returns NULL. -************************************************ -*/ -TS_STAMP *gsd_findlargest_ts(pCtrl, chan_count) -struct gsd_sync_ctrl *pCtrl; -int chan_count; -{ - TS_STAMP ts; - TS_STAMP *pTs = &ts; - struct gsd_sync_linked *pNchan; - int i; - - ts.secPastEpoch = 0; - ts.nsec = 0; - for (i = 0; i < chan_count; ++i) { - pNchan = pCtrl->pNstruct; - while(pNchan != NULL) { -/* - ca_printf(" %ld %ld >? %ld %ld\n", - (gsd_get_ts((pCtrl->pDstruct)->time_type, - pNchan->pNdata))->secPastEpoch, - (gsd_get_ts((pCtrl->pDstruct)->time_type, - pNchan->pNdata))->nsec, - pTs->secPastEpoch, pTs->nsec); -*/ - if(gsd_tss_gtr( - gsd_get_ts((pCtrl->pDstruct)->time_type,pNchan->pNdata), - pTs) || - gsd_tss_eq( - gsd_get_ts((pCtrl->pDstruct)->time_type, - pNchan->pNdata), pTs)) { - pTs = gsd_get_ts((pCtrl->pDstruct)->time_type,pNchan->pNdata); - } - pNchan = pNchan->pNstruct; - } - pCtrl++; - } - if(pTs == &ts) { - return NULL; - } - else { - return pTs; - } -} -/* -******************************************* -* Description: -* 1) Frees all event memory that was allocated on the fly by -* following each channel's linked list of gsd_sync_linked structures -******************************************* -*/ -VOID gsd_freeevent_mem(pCtrl) -struct gsd_sync_ctrl *pCtrl; -{ - struct gsd_sync_linked *pN; - struct gsd_sync_linked *pN_copy; - - pN = pCtrl->pNstruct; - - while(pN != NULL) { - if(pN->pNdata != NULL) { -/* - ca_printf("free %s %ld %ld\n", (pCtrl->pDstruct)->pName, - ((struct dbr_time_float *) (pN->pNdata))->stamp.secPastEpoch, - ((struct dbr_time_float *) (pN->pNdata))->stamp.nsec); -*/ - free(pN->pNdata); - } - pN_copy = pN; - pN = pN->pNstruct; - free(pN_copy); - } - pCtrl->pNstruct = NULL; - return; -} - -/* -******************************************* -* Description: -* 1) for every channel -* 1) If finds linked list data that is time stamped the -* same as pTs. -* 1) copies this data to the Next data buffer of -* the gsd_sync_ctrl structure -* 2) sets nvalid = 1 -* else -* 1) copies most recently received data to the -* Next data buffer of the gsd_sync_ctrl structure -* 2) clears nvalid = 0 -******************************************* -*/ -VOID gsd_syncset_findcopy(pCtrl, chan_count, pTs) -struct gsd_sync_ctrl *pCtrl; -int chan_count; -TS_STAMP *pTs; -{ - struct gsd_sync_linked *pNchan; - int i; - - for (i = 0; i < chan_count; ++i) { - pCtrl->nvalid = 0; - pNchan = pCtrl->pNstruct; - while(pNchan != NULL) { - if(gsd_tss_eq(gsd_get_ts((pCtrl->pDstruct)->time_type, - pNchan->pNdata), pTs)) { - gsd_copy_buffer(pNchan->pNdata, pCtrl->pNdata, - dbr_size_n((pCtrl->pDstruct)->time_type, - (pCtrl->pDstruct)->count)); - pCtrl->nvalid = 1; - break; - } - pNchan = pNchan->pNstruct; - } - - if((pCtrl->nvalid) != 1) { - if(pNchan = pCtrl->pNstruct) { - while(pNchan->pNstruct) pNchan = pNchan->pNstruct; - gsd_copy_buffer(pNchan->pNdata, pCtrl->pNdata, - dbr_size_n((pCtrl->pDstruct)->time_type, - (pCtrl->pDstruct)->count)); - } - } - - pCtrl++; - } - return; -} - -/* -************************************************* -* Description: -* 1) byte block transfer -************************************************* -*/ -VOID gsd_copy_buffer(pFrom, pTo, byte_count) -char *pFrom; -char *pTo; -unsigned int byte_count; -{ - unsigned int i; - for(i = 0; i < byte_count; ++i) { - *pTo++ = *pFrom++; - } - return; -} -/* -********************************************** -* Description: -* 1) Frees all allocated memory which resulted from calls to -* gsd_sync_init -* gsd_sync_read -********************************************** -*/ -VOID gsd_sync_clear(pSync_compctrl, chan_count) -struct gsd_sync_compctrl *pSync_compctrl; -unsigned int chan_count; -{ - int i; - struct gsd_sync_ctrl *pSync_ctrl = pSync_compctrl->pCtrl; - - if(NULL == pSync_compctrl) { - ca_printf("gsd_sync_clear: error NULL pSync_compctrl\n"); - return; - } - if(NULL == pSync_ctrl) { - free(pSync_compctrl); - ca_printf("gsd_sync_clear: error NULL pSync_ctrl\n"); - return; - } - - for(i = 0; i < chan_count; ++i) { - ca_clear_channel((pSync_ctrl->pDstruct)->pChid); - ca_flush_io(); - - if(pSync_ctrl->pNdata != NULL) free(pSync_ctrl->pNdata); - if(pSync_ctrl->pAdata != NULL) free(pSync_ctrl->pAdata); - if((pSync_ctrl->pDstruct)->pSdata != NULL) - free((pSync_ctrl->pDstruct)->pSdata); - (pSync_ctrl->pDstruct)->pSdata = NULL; - - pSync_ctrl++; - } - - free(pSync_compctrl->pCtrl); - free(pSync_compctrl); - - return; -} -/* -********************************************** -* Description: -* 1) if the two time stamps are within delta of each other then -* 1) return 1 -* 2) otherwise return 0 -********************************************** -*/ -int gsd_tss_within_delta(pTs_s, pTs_l, pDelta) -TS_STAMP *pTs_s; -TS_STAMP *pTs_l; -TS_STAMP *pDelta; -{ - TS_STAMP temp; - TS_STAMP *pTemp; - - if(gsd_tss_eq(pTs_s, pTs_l)) return 1; /* equal, so within delta */ - /* ensure that *pTs_l is the larger time stamp */ - if(gsd_tss_gtr(pTs_s, pTs_l)) { - pTemp = pTs_l; - pTs_l = pTs_s; - pTs_s = pTemp; - } - - temp.secPastEpoch = pTs_s->secPastEpoch + pDelta->secPastEpoch; - temp.nsec = pTs_s->nsec + pDelta->nsec; - - if((gsd_tss_gtr(&temp, pTs_l)) || (gsd_tss_eq(&temp, pTs_l))) - return 1; /* within delta */ - return 0; /* not within delta */ -} -/* -********************************************** -* Description: -* 1) if the two time stamps are equal then -* 1) return 1 -* 2) otherwise return 0 -********************************************** -*/ -int gsd_tss_eq(pTs_s, pTs_l) -TS_STAMP *pTs_s; -TS_STAMP *pTs_l; -{ - if((pTs_s == NULL) || (pTs_l == NULL)) return 0; /* not equal ts */ - if((pTs_s->secPastEpoch == pTs_l->secPastEpoch) && - (pTs_s->nsec == pTs_l->nsec)) return 1; /* equal time stamps */ - return 0; /* not equal time stamps */ -} -/* -********************************************** -* Description: -* 1) if time stamp 1 > time stamp 2 then -* 1) return 1 -* 2) otherwise return 0 -********************************************** -*/ -int gsd_tss_gtr(pTs_l, pTs_s) -TS_STAMP *pTs_l; -TS_STAMP *pTs_s; -{ - if((pTs_l == NULL) || (pTs_s == NULL)) return 0; /* not gtr than */ - if(pTs_l->secPastEpoch > pTs_s->secPastEpoch) return 1; /* gtr than */ - if((pTs_l->secPastEpoch == pTs_s->secPastEpoch) && - (pTs_l->nsec > pTs_s->nsec)) return 1; /* greater than */ - return 0; /* not greater than */ -} - - - -/* -* Note: UNIX specific routines below: !!!!!!!!!!!!!!!!!!!!!!!!! -*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -*/ -/* -************************************************ -* Description: -* 1) indicate when timeout occurs -* Note: UNIX gettimeofday apparently is the only C/system time -* routine to yield resolution below 1 second, but it is -* represented as being inaccurate in its usec element -* (see man gettimeofday) -************************************************ -*/ -int gsd_timeout(pCompctrl, timeout_secs, pfdctx) -struct gsd_sync_compctrl *pCompctrl; -float timeout_secs; -VOID **pfdctx; -{ - struct timeval new_gmt; - struct timezone zone; - - float dif_secs; - - gsd_ca_pend_event(pfdctx); /* allow C.A. events to occur */ - /* in the Unix environment */ - - gettimeofday(&new_gmt, &zone); - - if(new_gmt.tv_usec >= (pCompctrl->start_time).tv_usec) { - /* no borrow */ - dif_secs = ((float) (new_gmt.tv_sec - (pCompctrl->start_time).tv_sec)) + - (((float) (new_gmt.tv_usec - (pCompctrl->start_time).tv_usec)) / - 1000000.0); - } - else { - /* borrow */ - dif_secs = ((float) (new_gmt.tv_sec - (pCompctrl->start_time).tv_sec - 1)) + - (((float) (1000000 + new_gmt.tv_usec - (pCompctrl->start_time).tv_usec)) / - 1000000.0); - } - - if(dif_secs > timeout_secs) { - return 1; - } - - - return 0; -} -/* -********************************************** -********************************************** -*/ -void gsd_ca_task_initialize(pfdctx) -void **pfdctx; -{ - *pfdctx = (void *) fdmgr_init(); - if(!(*pfdctx)) { - ca_printf("gsd_ca_task_initialize: fdmgr_init failed.\n"); - abort(); - } - SEVCHK(ca_add_fd_registration(gsd_fd_register, *pfdctx), - "gsd_ca_task_initialize: Fd registration failed.\n"); - return; -} -/* -********************************************** -********************************************** -*/ -void gsd_ca_pend_event(pfdctx) -void **pfdctx; -{ - static struct timeval timeout = {0, USEC_TIME_OUT}; - fdmgr_pend_event(*pfdctx, &timeout); - return; -} - - -/* -************************************************ -* NAME -* gsd_fd_register(pfdcts, fd, condition) -* DESCRIPTION -* 1) if (condition is true) then -* 1) add file descriptor to fd manager -* else -* 1) delete file descriptor from fd manager -************************************************ -*/ -void gsd_fd_register(pfdctx, fd, condition) -void **pfdctx; -int fd; -int condition; -{ - if(condition) { - fdmgr_add_fd(pfdctx, fd, gsd_ca_service, NULL); - } - else { - fdmgr_clear_fd(pfdctx, fd); - } -} - -/* -************************************************* -* NAME -* gsd_ca_service() -* DESCRIPTION -* 1) call ca_pend_event to allow event handler execution -*************************************************** -*/ -void gsd_ca_service() -{ - ca_pend_event(PEND_EVENT_DELAY); -} -