|
|
@ -14,217 +14,216 @@ class TestTimer : public CxxTest::TestSuite
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
|
|
class DummyTimerThread : public Timer, public Thread
|
|
|
|
class DummyTimerUser : public TimerUser
|
|
|
|
{
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
|
|
DummyTimerThread( const int maxPeriodicCount = INT_MAX - 1,
|
|
|
|
DummyTimerUser() : m_counter( 0 ) { TRACE; }
|
|
|
|
const int signal = SIGALRM,
|
|
|
|
void timerExpired() { /*TRACE;*/ m_counter += 100; }
|
|
|
|
const time_t interval_sec = 2,
|
|
|
|
void timerDestroyed() { TRACE; m_counter++; };
|
|
|
|
const long interval_nsec = 0,
|
|
|
|
|
|
|
|
const time_t initExpr_sec = 0,
|
|
|
|
|
|
|
|
const long initExpr_nsec = 0 )
|
|
|
|
|
|
|
|
: Timer( signal )
|
|
|
|
|
|
|
|
, m_counter( 0 )
|
|
|
|
|
|
|
|
, m_maxPeriodicCount( maxPeriodicCount )
|
|
|
|
|
|
|
|
, m_signal ( signal )
|
|
|
|
|
|
|
|
, m_interval_sec( interval_sec )
|
|
|
|
|
|
|
|
, m_interval_nsec( interval_nsec )
|
|
|
|
|
|
|
|
, m_initExpr_sec( initExpr_sec )
|
|
|
|
|
|
|
|
, m_initExpr_nsec( initExpr_nsec )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
TRACE;
|
|
|
|
|
|
|
|
LOG( Logger::FINEST, ( std::string( "params: " ) +
|
|
|
|
|
|
|
|
stringify( maxPeriodicCount ) + " " +
|
|
|
|
|
|
|
|
stringify( signal ) + " " +
|
|
|
|
|
|
|
|
stringify( interval_sec ) + " " +
|
|
|
|
|
|
|
|
stringify( interval_nsec ) + " " +
|
|
|
|
|
|
|
|
stringify( initExpr_sec ) + " " +
|
|
|
|
|
|
|
|
stringify( initExpr_nsec ) ).c_str() );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
~DummyTimerThread()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
TRACE;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
int m_counter;
|
|
|
|
|
|
|
|
|
|
|
|
void* run()
|
|
|
|
}; // class TimerUser
|
|
|
|
{
|
|
|
|
|
|
|
|
TRACE;
|
|
|
|
|
|
|
|
createTimer( m_interval_sec,
|
|
|
|
|
|
|
|
m_interval_nsec,
|
|
|
|
|
|
|
|
m_initExpr_sec,
|
|
|
|
|
|
|
|
m_initExpr_nsec );
|
|
|
|
|
|
|
|
wait();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
|
|
void timerExpired()
|
|
|
|
void testBasicTimerThread( void )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TRACE;
|
|
|
|
TEST_HEADER;
|
|
|
|
m_counter += 100;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline void periodicTimerExpired()
|
|
|
|
DummyTimerUser timerUser;
|
|
|
|
{
|
|
|
|
Timer timer;
|
|
|
|
// logging take too much time at high freq
|
|
|
|
|
|
|
|
// TRACE;
|
|
|
|
timer.createTimer( &timerUser, 2 );
|
|
|
|
static int count = 0;
|
|
|
|
sleep( 4 );
|
|
|
|
m_counter++;
|
|
|
|
// no destroy
|
|
|
|
count++;
|
|
|
|
|
|
|
|
if ( count >= m_maxPeriodicCount ) {
|
|
|
|
TS_ASSERT_EQUALS( timerUser.m_counter, 100 );
|
|
|
|
stop();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void stop()
|
|
|
|
|
|
|
|
|
|
|
|
void testStopTimerThread( void )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
stopTimer();
|
|
|
|
TEST_HEADER;
|
|
|
|
sendSignal( m_signal );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int m_counter;
|
|
|
|
DummyTimerUser timerUser;
|
|
|
|
|
|
|
|
Timer timer;
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
timer_t timerId = timer.createTimer( &timerUser, 10 );
|
|
|
|
|
|
|
|
sleep( 2 );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId );
|
|
|
|
|
|
|
|
|
|
|
|
int m_maxPeriodicCount;
|
|
|
|
TS_ASSERT_EQUALS( timerUser.m_counter, 1 );
|
|
|
|
int m_signal;
|
|
|
|
}
|
|
|
|
time_t m_interval_sec;
|
|
|
|
|
|
|
|
long m_interval_nsec;
|
|
|
|
|
|
|
|
time_t m_initExpr_sec;
|
|
|
|
|
|
|
|
long m_initExpr_nsec;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}; // class DummyTimerThread
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void testBasicTimerThread( void )
|
|
|
|
|
|
|
|
|
|
|
|
void testPeriodicTimerThread( void )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TEST_HEADER;
|
|
|
|
TEST_HEADER;
|
|
|
|
|
|
|
|
|
|
|
|
// the main thread shall ignore the SIGALRM
|
|
|
|
DummyTimerUser timerUser;
|
|
|
|
sigset_t set;
|
|
|
|
Timer timer;
|
|
|
|
sigemptyset( &set );
|
|
|
|
|
|
|
|
sigaddset( &set, SIGALRM );
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_BLOCK, &set, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DummyTimerThread t(5);
|
|
|
|
timer_t timerId = timer.createTimer( &timerUser,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
1, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
t.start();
|
|
|
|
|
|
|
|
sleep(4);
|
|
|
|
sleep(4);
|
|
|
|
t.join();
|
|
|
|
timer.stopTimer( timerId );
|
|
|
|
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( t.m_counter, 100 );
|
|
|
|
sleep(4); // did it really stopped?
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( timerUser.m_counter, 400 + 1 );
|
|
|
|
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_UNBLOCK, &set, 0 );
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void testStopTimerThread( void )
|
|
|
|
|
|
|
|
|
|
|
|
void testTimerThreadHighFreq( void )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TEST_HEADER;
|
|
|
|
TEST_HEADER;
|
|
|
|
|
|
|
|
|
|
|
|
// the main thread shall ignore the SIGALRM
|
|
|
|
int nano = 1000000000; // 10^9
|
|
|
|
sigset_t set;
|
|
|
|
int freq = 200;
|
|
|
|
sigemptyset( &set );
|
|
|
|
|
|
|
|
sigaddset( &set, SIGALRM );
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_BLOCK, &set, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DummyTimerThread t(5, SIGALRM, 10);
|
|
|
|
DummyTimerUser timerUser;
|
|
|
|
|
|
|
|
Timer timer;
|
|
|
|
|
|
|
|
|
|
|
|
t.start();
|
|
|
|
timer_t timerId = timer.createTimer( &timerUser,
|
|
|
|
sleep(1);
|
|
|
|
1, 0,
|
|
|
|
t.stop();
|
|
|
|
0, nano / freq );
|
|
|
|
t.join();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( t.m_counter, 0 );
|
|
|
|
int circle = 2;
|
|
|
|
|
|
|
|
sleep( 1 + circle );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId );
|
|
|
|
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_UNBLOCK, &set, 0 );
|
|
|
|
TS_ASSERT_DELTA ( timerUser.m_counter, 100 * freq * circle + 1,
|
|
|
|
|
|
|
|
(100 * freq * circle + 1 ) * 0.9);
|
|
|
|
|
|
|
|
sleep(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void testPeriodicTimerThread( void )
|
|
|
|
void testOneUserManyTimers( void )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TEST_HEADER;
|
|
|
|
TEST_HEADER;
|
|
|
|
|
|
|
|
|
|
|
|
// the main thread shall ignore the SIGALRM
|
|
|
|
DummyTimerUser timerUser;
|
|
|
|
sigset_t set;
|
|
|
|
Timer timer;
|
|
|
|
sigemptyset( &set );
|
|
|
|
|
|
|
|
sigaddset( &set, SIGALRM );
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_BLOCK, &set, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DummyTimerThread t( 1000,
|
|
|
|
timer_t timerId = timer.createTimer( &timerUser,
|
|
|
|
SIGALRM,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
1, 0,
|
|
|
|
1, 0 );
|
|
|
|
1, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
t.start();
|
|
|
|
timer_t timerId2 = timer.createTimer( &timerUser,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
2, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timer_t timerId3 = timer.createTimer( &timerUser,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
3, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sleep(4);
|
|
|
|
|
|
|
|
timer.stopTimer( timerId );
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( timerUser.m_counter, 400 + 200 + 200 + 1 );
|
|
|
|
|
|
|
|
|
|
|
|
sleep(4);
|
|
|
|
sleep(4);
|
|
|
|
t.stop();
|
|
|
|
TS_ASSERT_EQUALS( timerUser.m_counter, 400 + 200 + 200 + 200 + 100 + 1 );
|
|
|
|
sleep(2);
|
|
|
|
|
|
|
|
t.join();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( t.m_counter, 102 );
|
|
|
|
timer.stopTimer( timerId2 );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId3 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sleep(1);
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( timerUser.m_counter, 400 + 200 + 200 + 200 + 100 + 3 );
|
|
|
|
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_UNBLOCK, &set, 0 );
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void testCustomSignal( void )
|
|
|
|
void testMenyUserManyTimers( void )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TEST_HEADER;
|
|
|
|
TEST_HEADER;
|
|
|
|
|
|
|
|
|
|
|
|
int customSignal = SIGRTMIN;
|
|
|
|
DummyTimerUser timerUser;
|
|
|
|
|
|
|
|
DummyTimerUser timerUser2;
|
|
|
|
|
|
|
|
DummyTimerUser timerUser3;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Timer timer;
|
|
|
|
|
|
|
|
|
|
|
|
// the main thread shall ignore the customSignal
|
|
|
|
timer_t timerId = timer.createTimer( &timerUser,
|
|
|
|
sigset_t set;
|
|
|
|
1, 0,
|
|
|
|
sigemptyset( &set );
|
|
|
|
1, 0 );
|
|
|
|
sigaddset( &set, customSignal );
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_BLOCK, &set, 0 );
|
|
|
|
timer_t timerId2 = timer.createTimer( &timerUser,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
2, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timer_t timerId3 = timer.createTimer( &timerUser,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
3, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timer_t timerId4 = timer.createTimer( &timerUser2,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
1, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timer_t timerId5 = timer.createTimer( &timerUser2,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
2, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
DummyTimerThread t( 5, customSignal );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t.start();
|
|
|
|
|
|
|
|
sleep(4);
|
|
|
|
sleep(4);
|
|
|
|
t.join();
|
|
|
|
TS_ASSERT_EQUALS( timerUser.m_counter, 400 + 200 + 200 );
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( timerUser2.m_counter, 400 + 200 );
|
|
|
|
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( t.m_counter, 100 );
|
|
|
|
timer.stopTimer( timerId );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId2 );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId3 );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId4 );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId5 );
|
|
|
|
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_UNBLOCK, &set, 0 );
|
|
|
|
sleep(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void testTimerThreadHighFreq( void )
|
|
|
|
void test2Timer( void )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
TEST_HEADER;
|
|
|
|
TEST_HEADER;
|
|
|
|
|
|
|
|
|
|
|
|
// the main thread shall ignore the SIGALRM
|
|
|
|
DummyTimerUser timerUser;
|
|
|
|
sigset_t set;
|
|
|
|
DummyTimerUser timerUser2;
|
|
|
|
sigemptyset( &set );
|
|
|
|
DummyTimerUser itmerUser3;
|
|
|
|
sigaddset( &set, SIGALRM );
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_BLOCK, &set, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int nano = 1000000000; // 10^9
|
|
|
|
Timer timer;
|
|
|
|
int freq = 200;
|
|
|
|
Timer timer2;
|
|
|
|
DummyTimerThread t( INT_MAX - 1,
|
|
|
|
|
|
|
|
SIGALRM,
|
|
|
|
timer_t timerId = timer.createTimer( &timerUser,
|
|
|
|
1, 0,
|
|
|
|
1, 0,
|
|
|
|
0, nano / freq );
|
|
|
|
1, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
t.start();
|
|
|
|
timer_t timerId2 = timer.createTimer( &timerUser,
|
|
|
|
int circle = 4;
|
|
|
|
1, 0,
|
|
|
|
sleep( 1 + circle );
|
|
|
|
2, 0 );
|
|
|
|
t.stop();
|
|
|
|
|
|
|
|
t.join();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// expected 800000 + 100 got 795510
|
|
|
|
timer_t timerId3 = timer2.createTimer( &timerUser,
|
|
|
|
// accurcy: ~ > 99.5%
|
|
|
|
1, 0,
|
|
|
|
TS_ASSERT_DELTA ( t.m_counter, 100 + freq * circle, (100 + freq * circle) * 0.995);
|
|
|
|
3, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timer_t timerId4 = timer.createTimer( &timerUser2,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
1, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timer_t timerId5 = timer2.createTimer( &timerUser2,
|
|
|
|
|
|
|
|
1, 0,
|
|
|
|
|
|
|
|
2, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
LOG( Logger::FINEST, ( std::string( "got: " ) + stringify( t.m_counter ) + " "
|
|
|
|
|
|
|
|
+ "expected: " + stringify( 100 + freq * circle ) ).c_str() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pthread_sigmask( SIG_UNBLOCK, &set, 0 );
|
|
|
|
sleep(4);
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( timerUser.m_counter, 400 + 200 + 200 );
|
|
|
|
|
|
|
|
TS_ASSERT_EQUALS( timerUser2.m_counter, 400 + 200 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timer.stopTimer( timerId );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId2 );
|
|
|
|
|
|
|
|
timer2.stopTimer( timerId3 );
|
|
|
|
|
|
|
|
timer.stopTimer( timerId4 );
|
|
|
|
|
|
|
|
timer2.stopTimer( timerId5 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sleep(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|