diff --git a/src/ca/CAref.html b/src/ca/CAref.html
index 77d7b4bd7..c4cee37f8 100644
--- a/src/ca/CAref.html
+++ b/src/ca/CAref.html
@@ -2808,11 +2808,14 @@ additional network bandwidth and server CPU load when searching for
unresolved channels.
-caEventRate <PV name>
+caEventRate <PV name> [subscription count]
Description
-Subscribe to the specified PV and periodically log its event rate.
+Connect to the specified PV, subscribe for monitor updates the specified
+number of times (default once), and periodically log the current sampled
+event rate, average event rate, and the standard deviation of the event rate
+in Hertz to standard out.
ca_test <PV name> [value to be written]
diff --git a/src/ca/caEventRate.cpp b/src/ca/caEventRate.cpp
index 9af789201..4498eea36 100644
--- a/src/ca/caEventRate.cpp
+++ b/src/ca/caEventRate.cpp
@@ -10,6 +10,7 @@
#include
#include
+#include
#include "cadef.h"
#include "dbDefs.h"
@@ -25,44 +26,69 @@ extern "C" void eventCallBack ( struct event_handler_args args )
(*pCount)++;
}
-
/*
* caEventRate ()
*/
-void caEventRate ( const char *pName )
+void caEventRate ( const char *pName, unsigned count )
{
static const double initialSamplePeriod = 1.0;
static const double maxSamplePeriod = 60.0 * 60.0;
+ printf ( "Connecting to CA Channel \"%s\".", pName );
+ fflush ( stdout );
+
chid chan;
int status = ca_search ( pName, &chan );
SEVCHK(status, NULL);
- unsigned eventCount = 0u;
- status = ca_add_event ( DBR_FLOAT, chan, eventCallBack, &eventCount, NULL);
- SEVCHK ( status, __FILE__ );
-
status = ca_pend_io ( 10.0 );
if ( status != ECA_NORMAL ) {
fprintf ( stderr, "caEventRate: %s not found\n", pName );
return;
}
+ printf ( " done.\n" );
+
+ printf ( "Subscribing %u times.", count );
+ fflush ( stdout );
+
+ unsigned eventCount = 0u;
+ for ( unsigned i = 0u; i < count; i++ ) {
+ status = ca_add_event ( DBR_FLOAT, chan, eventCallBack, &eventCount, NULL);
+ SEVCHK ( status, __FILE__ );
+ }
+
+ status = ca_flush_io ();
+ SEVCHK ( status, __FILE__ );
+
+ printf ( " done.\n" );
+
+ printf ( "Waiting for initial value events." );
+ fflush ( stdout );
+
// let the first one go by
- while ( eventCount < 1u ) {
+ while ( eventCount < count ) {
status = ca_pend_event ( 0.01 );
if ( status != ECA_TIMEOUT ) {
SEVCHK ( status, NULL );
}
}
+ printf ( " done.\n" );
+
double samplePeriod = initialSamplePeriod;
+ double X = 0.0;
+ double XX = 0.0;
+ double test = 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 );
}
@@ -71,11 +97,22 @@ void caEventRate ( const char *pName )
nEvents = curEventCount - lastEventCount;
}
else {
- nEvents = ( UINT_MAX - lastEventCount ) + curEventCount +1u;
+ nEvents = ( UINT_MAX - lastEventCount ) + curEventCount + 1u;
}
- errlogPrintf ( "CA Channel \"%s\" is producing %g subscription update events per second.\n",
- pName, nEvents / samplePeriod );
+ 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;
diff --git a/src/ca/caEventRateMain.cpp b/src/ca/caEventRateMain.cpp
index c783ad8b5..725e66102 100644
--- a/src/ca/caEventRateMain.cpp
+++ b/src/ca/caEventRateMain.cpp
@@ -11,15 +11,28 @@
#include
#include
-void caEventRate ( const char *pName );
+void caEventRate ( const char *pName, unsigned count );
int main ( int argc, char **argv )
{
- if ( argc < 2 || argc > 2 ) {
- printf ( "usage: %s < PV name >\n", argv[0] );
+ if ( argc < 2 || argc > 3 ) {
+ fprintf ( stderr, "usage: %s < PV name > [subscription count]\n", argv[0] );
+ return 0;
}
- caEventRate ( argv[1] );
+ unsigned count;
+ if ( argc == 3 ) {
+ int status = sscanf ( argv[2], " %u ", & count );
+ if ( status != 1 ) {
+ fprintf ( stderr, "expected unsigned integer 2nd argument\n" );
+ return 0;
+ }
+ }
+ else {
+ count = 1;
+ }
+
+ caEventRate ( argv[1], count );
return 0;
}