From a570a5c17f089c383944c5e8eb8c63bec85bb317 Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Thu, 1 May 2003 23:18:33 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'B3.13'. --- src/ca/caEventRate.cpp | 134 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 src/ca/caEventRate.cpp diff --git a/src/ca/caEventRate.cpp b/src/ca/caEventRate.cpp new file mode 100644 index 000000000..be8f30360 --- /dev/null +++ b/src/ca/caEventRate.cpp @@ -0,0 +1,134 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +#include +#include +#include + +#include "cadef.h" +#include "dbDefs.h" +#include "epicsTime.h" +#include "errlog.h" + +/* + * event_handler() + */ +extern "C" void eventCallBack ( struct event_handler_args args ) +{ + unsigned *pCount = static_cast < unsigned * > ( args.usr ); + (*pCount)++; +} + +/* + * caEventRate () + */ +void caEventRate ( const char *pName, unsigned count ) +{ + unsigned i; + static const double initialSamplePeriod = 1.0; + static const double maxSamplePeriod = 60.0 * 5.0; + + printf ( "Connecting to CA Channel \"%s\" %u times.", + pName, count ); + fflush ( stdout ); + + chid * pChidTable = new chid [ count ]; + assert ( pChidTable ); + epicsTime begin = epicsTime::getCurrent (); + for ( i = 0u; i < count; i++ ) { + int status = ca_search ( pName, & pChidTable[i] ); + SEVCHK ( status, NULL ); + } + + int status = ca_pend_io ( 10000.0 ); + if ( status != ECA_NORMAL ) { + fprintf ( stderr, " not found.\n" ); + return; + } + epicsTime end = epicsTime::getCurrent (); + + printf ( " done(%f sec).\n", end - begin ); + + printf ( "Subscribing %u times.", count ); + fflush ( stdout ); + + unsigned eventCount = 0u; + begin = epicsTime::getCurrent (); + for ( i = 0u; i < count; i++ ) { + status = ca_add_event ( DBR_FLOAT, + pChidTable[i], eventCallBack, &eventCount, NULL); + SEVCHK ( status, __FILE__ ); + } + + status = ca_flush_io (); + SEVCHK ( status, __FILE__ ); + + end = epicsTime::getCurrent (); + + printf ( " done(%f sec).\n", end - begin ); + + printf ( "Waiting for initial value events." ); + fflush ( stdout ); + + // let the first one go by + begin = epicsTime::getCurrent (); + while ( eventCount < count ) { + status = ca_pend_event ( 0.01 ); + if ( status != ECA_TIMEOUT ) { + SEVCHK ( status, NULL ); + } + } + end = epicsTime::getCurrent (); + + printf ( " done(%f sec).\n", end - begin ); + + double samplePeriod = initialSamplePeriod; + double X = 0.0; + double XX = 0.0; + unsigned N = 0u; + while ( true ) { + unsigned nEvents, lastEventCount, curEventCount; + + epicsTime begin = epicsTime::getCurrent (); + lastEventCount = eventCount; + status = ca_pend_event ( samplePeriod ); + curEventCount = eventCount; + epicsTime end = epicsTime::getCurrent (); + if ( status != ECA_TIMEOUT ) { + SEVCHK ( status, NULL ); + } + + if ( curEventCount >= lastEventCount ) { + nEvents = curEventCount - lastEventCount; + } + else { + nEvents = ( UINT_MAX - lastEventCount ) + curEventCount + 1u; + } + + N++; + + double period = end - begin; + double Hz = nEvents / period; + + X += Hz; + XX += Hz * Hz; + + double mean = X / N; + double stdDev = sqrt ( XX / N - mean * mean ); + + printf ( "CA Event Rate (Hz): current %g mean %g std dev %g\n", + Hz, mean, stdDev ); + + if ( samplePeriod < maxSamplePeriod ) { + samplePeriod += samplePeriod; + } + } +} +