From 37977cef1ba495beb7c5c564fb873efedc19da69 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Thu, 15 Feb 2001 17:32:06 +0000 Subject: [PATCH] installed --- src/libCom/test/epicsTimerTest.cpp | 337 +++++++++++++++++++++++++ src/libCom/test/epicsTimerTestMain.cpp | 38 +++ 2 files changed, 375 insertions(+) create mode 100644 src/libCom/test/epicsTimerTest.cpp create mode 100644 src/libCom/test/epicsTimerTestMain.cpp diff --git a/src/libCom/test/epicsTimerTest.cpp b/src/libCom/test/epicsTimerTest.cpp new file mode 100644 index 000000000..2f78e32c5 --- /dev/null +++ b/src/libCom/test/epicsTimerTest.cpp @@ -0,0 +1,337 @@ +/* + * $Id$ + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + */ + +#include + +#include "epicsTimer.h" +#include "epicsEvent.h" +#include "epicsAssert.h" +#include "tsFreeList.h" + +class delayVerify : public epicsTimerNotify { +public: + delayVerify ( double expectedDelay, epicsTimerQueueThreaded & ); + expireStatus expire (); + void * operator new ( size_t size ); + void operator delete ( void *pCadaver, size_t size ); + void start ( const epicsTime &expireTime ); + void setBegin ( const epicsTime & ); + double delay () const; + void checkError () const; +protected: + virtual ~delayVerify (); +private: + epicsTimer &timer; + epicsTime beginStamp; + epicsTime expireStamp; + double expectedDelay; + static tsFreeList < class delayVerify, 0x20 > freeList; +}; + +static unsigned expireCount; +static epicsEvent expireEvent; + +delayVerify::delayVerify ( double expectedDelayIn, epicsTimerQueueThreaded &queue ) : + timer ( queue.createTimer ( *this ) ), expectedDelay ( expectedDelayIn ) +{ +} + +delayVerify::~delayVerify () +{ +} + +inline void delayVerify::setBegin ( const epicsTime &beginIn ) +{ + this->beginStamp = beginIn; +} + +inline double delayVerify::delay () const +{ + return this->expectedDelay; +} + +void delayVerify::checkError () const +{ + double actualDelay = this->expireStamp - this->beginStamp; + double measuredError = actualDelay - this->expectedDelay; + double percentError = measuredError /= this->expectedDelay; + percentError *= 100.0; + if ( percentError > 1.0 ) { + printf ( "TEST FAILED timer delay = %f sec, error = %f sec (%f %%)\n", + this->expectedDelay, measuredError, percentError ); + } +} + +inline void delayVerify::start ( const epicsTime &expireTime ) +{ + this->timer.start ( expireTime ); +} + +tsFreeList < class delayVerify, 0x20 > delayVerify::freeList; + +inline void * delayVerify::operator new ( size_t size ) +{ + return delayVerify::freeList.allocate ( size ); +} + +inline void delayVerify::operator delete ( void *pCadaver, size_t size ) +{ + delayVerify::freeList.release ( pCadaver, size ); +} + +epicsTimerNotify::expireStatus delayVerify::expire () +{ + this->expireStamp = epicsTime::getCurrent (); + if ( --expireCount == 0u ) { + expireEvent.signal (); + } + return noRestart; +} + +// +// verify reasonable timer interval accuracy +// +void testAccuracy () +{ + static const unsigned nTimers = 25u; + delayVerify *pTimers[nTimers]; + unsigned i; + + epicsTimerQueueThreaded &queue = epicsTimerQueueThreaded::create ( true, epicsThreadPriorityMax ); + + for ( i = 0u; i < nTimers; i++ ) { + pTimers[i] = new delayVerify ( ( nTimers - i ) * 0.1, queue ); + assert ( pTimers[i] ); + } + expireCount = nTimers; + for ( i = 0u; i < nTimers; i++ ) { + epicsTime cur = epicsTime::getCurrent (); + pTimers[i]->setBegin ( cur ); + pTimers[i]->start ( cur + pTimers[i]->delay () ); + } + while ( expireCount != 0u ) { + expireEvent.wait (); + } + for ( i = 0u; i < nTimers; i++ ) { + pTimers[i]->checkError (); + } + queue.release (); +} + +class cancelVerify : public epicsTimerNotify { +public: + cancelVerify ( double expectedDelay, epicsTimerQueueThreaded & ); + expireStatus expire (); + void * operator new ( size_t size ); + void operator delete ( void *pCadaver, size_t size ); + void start ( const epicsTime &expireTime ); + void cancel (); +protected: + virtual ~cancelVerify (); +private: + epicsTimer &timer; + bool failOutIfExpireIsCalled; + static tsFreeList < class cancelVerify, 0x20 > freeList; +}; + +cancelVerify::cancelVerify ( double expectedDelayIn, epicsTimerQueueThreaded &queue ) : + timer ( queue.createTimer ( *this ) ), failOutIfExpireIsCalled ( false ) +{ +} + +cancelVerify::~cancelVerify () +{ +} + +inline void cancelVerify::start ( const epicsTime &expireTime ) +{ + this->timer.start ( expireTime ); +} + +tsFreeList < class cancelVerify, 0x20 > cancelVerify::freeList; + +inline void * cancelVerify::operator new ( size_t size ) +{ + return cancelVerify::freeList.allocate ( size ); +} + +inline void cancelVerify::operator delete ( void *pCadaver, size_t size ) +{ + cancelVerify::freeList.release ( pCadaver, size ); +} + +inline void cancelVerify::cancel () +{ + this->timer.cancel (); + this->failOutIfExpireIsCalled = true; +} + +epicsTimerNotify::expireStatus cancelVerify::expire () +{ + double root = 3.14159; + for ( unsigned i = 0u; i < 10000; i++ ) { + root = sqrt ( root ); + } + assert ( ! this->failOutIfExpireIsCalled ); + return noRestart; +} + +// +// verify that when cancel() is calle dthe timer never runs again +// +void testCancel () +{ + static const unsigned nTimers = 25u; + cancelVerify *pTimers[nTimers]; + unsigned i; + + epicsTimerQueueThreaded &queue = epicsTimerQueueThreaded::create ( true, epicsThreadPriorityMin ); + + for ( i = 0u; i < nTimers; i++ ) { + pTimers[i] = new cancelVerify ( ( nTimers - i ) * 0.1, queue ); + assert ( pTimers[i] ); + } + epicsTime cur = epicsTime::getCurrent (); + for ( i = 0u; i < nTimers; i++ ) { + pTimers[i]->start ( cur + 4.0 ); + } + epicsThreadSleep ( 5.0 ); + for ( i = 0u; i < nTimers; i++ ) { + pTimers[i]->cancel (); + } + epicsThreadSleep ( 1.0 ); + queue.release (); +} + +class periodicVerify : public epicsTimerNotify { +public: + periodicVerify ( double expectedDelay, epicsTimerQueueThreaded & ); + expireStatus expire (); + void * operator new ( size_t size ); + void operator delete ( void *pCadaver, size_t size ); + void start ( const epicsTime &expireTime ); + void cancel (); + void verifyCount (); +protected: + virtual ~periodicVerify (); +private: + unsigned nExpire; + epicsTimer &timer; + bool failOutIfExpireIsCalled; + static tsFreeList < class periodicVerify, 0x20 > freeList; +}; + +periodicVerify::periodicVerify ( double expectedDelayIn, epicsTimerQueueThreaded &queue ) : + nExpire ( 0u ), timer ( queue.createTimer ( *this ) ), failOutIfExpireIsCalled ( false ) + +{ +} + +periodicVerify::~periodicVerify () +{ +} + +inline void periodicVerify::start ( const epicsTime &expireTime ) +{ + this->timer.start ( expireTime ); +} + +tsFreeList < class periodicVerify, 0x20 > periodicVerify::freeList; + +inline void * periodicVerify::operator new ( size_t size ) +{ + return periodicVerify::freeList.allocate ( size ); +} + +inline void periodicVerify::operator delete ( void *pCadaver, size_t size ) +{ + periodicVerify::freeList.release ( pCadaver, size ); +} + +inline void periodicVerify::cancel () +{ + this->timer.cancel (); + this->failOutIfExpireIsCalled = true; +} + +inline void periodicVerify::verifyCount () +{ + assert ( this->nExpire > 1u ); +} + +epicsTimerNotify::expireStatus periodicVerify::expire () +{ + this->nExpire++; + double root = 3.14159; + for ( unsigned i = 0u; i < 10000; i++ ) { + root = sqrt ( root ); + } + assert ( ! this->failOutIfExpireIsCalled ); + double delay = rand (); + delay = delay / RAND_MAX; + delay /= 10.0; + return expireStatus ( restart, delay ); +} + +// +// verify periodic timers +// +void testPeriodic () +{ + static const unsigned nTimers = 25u; + periodicVerify *pTimers[nTimers]; + unsigned i; + + epicsTimerQueueThreaded &queue = epicsTimerQueueThreaded::create ( true, epicsThreadPriorityMin ); + + for ( i = 0u; i < nTimers; i++ ) { + pTimers[i] = new periodicVerify ( ( nTimers - i ) * 0.1, queue ); + assert ( pTimers[i] ); + } + epicsTime cur = epicsTime::getCurrent (); + for ( i = 0u; i < nTimers; i++ ) { + pTimers[i]->start ( cur ); + } + epicsThreadSleep ( 5.0 ); + for ( i = 0u; i < nTimers; i++ ) { + pTimers[i]->verifyCount (); + pTimers[i]->cancel (); + } + epicsThreadSleep ( 1.0 ); + queue.release (); +} + +void epicsTimerTest () +{ + testAccuracy (); + testCancel (); + testPeriodic (); + printf ( "test complete\n" ); +} diff --git a/src/libCom/test/epicsTimerTestMain.cpp b/src/libCom/test/epicsTimerTestMain.cpp new file mode 100644 index 000000000..d1a91cc91 --- /dev/null +++ b/src/libCom/test/epicsTimerTestMain.cpp @@ -0,0 +1,38 @@ + +/* + * $Id$ + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + */ + +void epicsTimerTest ( void ); + +int main ( int argc, char *argv[] ) +{ + epicsTimerTest (); + return 0; +}