Timer update

master
Denes Matetelki 14 years ago
parent 6792784464
commit f39d876cc2

@ -11,9 +11,9 @@ public:
Timer( const int signal = SIGALRM );
virtual ~Timer() {}
virtual void timerExpired() {}
virtual void periodicTimerExpired() {}
virtual ~Timer();
virtual void timerExpired() {};
virtual void periodicTimerExpired() {};
void createTimer( const time_t interval_sec,
const long interval_nsec = 0,
@ -29,8 +29,8 @@ public:
private:
// after turning on all warnings, gcc reports that the class has pointer
// data members (time_t, which is an int by the way) so copy ctor and
// assign op shall be inmplemented
// data members (time_t, which is a long int by the way) so copy ctor and
// assign op shall be declared
Timer( const Timer& timer );
Timer& operator=( const Timer& );
@ -39,6 +39,7 @@ private:
timer_t m_timerId;
bool m_periodic;
bool m_running;
sigset_t m_mask;
}; // class Timer

@ -7,24 +7,49 @@
#include <string.h> // strerror
/// @note not used now
// static void sigHandler(int sig, siginfo_t *si, void *uc)
// {
// TRACE_STATIC;
//
// }
struct sigaction& sigActionInit( struct sigaction &sigAct, const int signal )
{
sigAct.sa_flags = SA_SIGINFO;
// sigAct.sa_sigaction = sigHandler;
sigemptyset( &sigAct.sa_mask );
sigaddset( &sigAct.sa_mask, signal );
sigaction( signal, &sigAct, 0 );
return sigAct;
}
sigset_t& sigSetInit( sigset_t &sigSet, const int signal )
{
sigemptyset( &sigSet );
sigaddset(&sigSet, signal );
sigprocmask(SIG_SETMASK, &sigSet, NULL);
return sigSet;
}
Timer::Timer( const Timer& timer )
: m_signal( timer.m_signal )
Timer::Timer( const int signal )
: m_signal( signal )
, m_sigAction( sigActionInit( m_sigAction , m_signal ) )
, m_timerId( 0 )
, m_periodic( false )
, m_running( true )
, m_mask( sigSetInit( m_mask, m_signal ) )
{
TRACE;
}
Timer::~Timer()
{
TRACE;
sigprocmask(SIG_UNBLOCK, &m_mask, NULL);
}
@ -40,7 +65,10 @@ void Timer::createTimer( const time_t interval_sec,
sigev.sigev_notify = SIGEV_SIGNAL;
sigev.sigev_signo = m_signal;
sigev.sigev_value.sival_ptr = &m_timerId;
timer_create( CLOCK_MONOTONIC, &sigev, &m_timerId );
timer_create( CLOCK_REALTIME, &sigev, &m_timerId );
LOG( Logger::FINEST, ( std::string( "Timer created with ID: " ) +
stringify( m_timerId ) ).c_str() );
// arm it
struct itimerspec its;
@ -58,15 +86,30 @@ void Timer::wait()
{
TRACE;
int sig;
sigwait( &m_sigAction.sa_mask, &sig );
/// @note timerID is acquired from the siginfo after all
long* tidp;
siginfo_t sigInfo;
sigwaitinfo( &(m_sigAction.sa_mask), &sigInfo);
tidp = (long*)sigInfo.si_value.sival_ptr;
// LOG( Logger::FINEST, ( std::string( "Timer expired with ID: " ) +
// stringify( (timer_t)*tidp ) ).c_str() );
timerExpired();
if ( m_periodic ) {
while ( m_running ) {
sigwait( &m_sigAction.sa_mask, &sig );
sigwaitinfo( &(m_sigAction.sa_mask), &sigInfo);
tidp = (long*)sigInfo.si_value.sival_ptr;
// LOG( Logger::FINEST, ( std::string( "Timer expired with ID:" ) +
// stringify( (timer_t)*tidp ) ).c_str() );
periodicTimerExpired();
}
}
}
@ -88,21 +131,3 @@ void Timer::gracefulStop()
m_running = false;
}
Timer::Timer( const int signal )
: m_signal( signal )
, m_sigAction( sigActionInit( m_sigAction , m_signal ) )
, m_timerId( 0 )
, m_periodic( false )
, m_running( true )
{
TRACE;
}
Timer& Timer::operator=( const Timer& )
{
TRACE;
return *this;
}

@ -1,15 +1,51 @@
#!/usr/bin/perl
use strict;
use warnings;
use Term::ANSIColor qw(:constants);
$Term::ANSIColor::AUTORESET = 1;
my $line = "";
my $left;
while ( <> ) {
if (/Segmentation fault/) {
print "\n" . YELLOW . "Segmentation fault." . RESET . "\n";
$left = 3;
next;
}
if (/^(Thread \d+)/) {
print "\n" . BOLD BLUE . $1 . RESET . " $'"
print "\n" . BOLD BLUE . $1 . RESET . " $'";
next;
}
elsif ( /^(#\d+)\s+(\S+)\s+in\s+(.+)( \(.*)(at.*\/)(\S+):(\d+)/ )
if ($left) {
if ( $left == 3 ) {
$line = $_;
chomp($line);
$left--;
next;
}
elsif ( $left == 2 ) {
$line .= $_;
$left--;
}
elsif ( $left == 1 ) {
print BOLD YELLOW . $_ . RESET . "\n";
$left--;
next;
}
} else {
$line = $_;
}
if ( $line =~ /^(#\d+)\s+(\S+)\s+in\s+(.+)( \(.*)(at.*\/)(\S+):(\d+)/ )
{
print "\n" .
BOLD . $1 . # no
@ -21,7 +57,7 @@ while ( <> ) {
YELLOW . $7 . # line
RESET . "\n";
}
elsif ( /^(#\d+)\s+(\S+)\s+in\s+(.+)( \(.*)(from.*\/)(\S+)/ )
elsif ( $line =~ /^(#\d+)\s+(\S+)\s+in\s+(.+)( \(.*)(from.*\/)(\S+)/ )
{
print "\n" .
BOLD . $1 . # no

@ -4,18 +4,18 @@
# ./run_test.sh <TEST_BINARY>
# function yesno()
# {
# while true; do
# read -p "$* (y/n)[y]" yn
# if [ "$yn" = '' ]; then yn="y"; fi
# case "$yn" in
# [Yy]* ) return 0;;
# [Nn]* ) return 1;;
# * ) echo "Please answer y/n.";;
# esac
# done
# }
function yesno()
{
while true; do
read -p "$* (y/n)[y]" yn
if [ "$yn" = '' ]; then yn="y"; fi
case "$yn" in
[Yy]* ) return 0;;
[Nn]* ) return 1;;
* ) echo "Please answer y/n.";;
esac
done
}
pre="\E[00;33m"
fail="\E[00;31m"
@ -80,12 +80,14 @@ if [ $retval -ne 0 ]; then
if [ "$cores" != "" ]; then
echo -e "${pre}Core file generated: ${post}"
echo $cores
# if yesno "run 'gdb $test $cores' ?"; then
# gdb $test $cores
# fi
# NOTE no need to bt full
gdb $test $cores -ex "set width 1000" -ex "thread apply all bt" -ex q > gdb.out
./gdb_out_parser.pl gdb.out
if yesno "run 'gdb $test $cores' ?"; then
gdb $test $cores
fi
fi
exit -1
fi

@ -18,8 +18,9 @@ private:
{
public:
DummyTimer(int maxPeriodicCount = 5)
: m_counter(0)
DummyTimer(int maxPeriodicCount = 5, const int signal = SIGALRM)
: Timer(signal)
, m_counter(0)
, m_maxPeriodicCount(maxPeriodicCount)
{
TRACE;
@ -80,11 +81,13 @@ private:
public:
DummyTimerThread( const int maxPeriodicCount = INT_MAX - 1,
const int signal = SIGALRM,
const time_t interval_sec = 2,
const long interval_nsec = 0,
const time_t initExpr_sec = 0,
const long initExpr_nsec = 0 )
: m_counter(0)
: Timer(signal)
, m_counter(0)
, m_maxPeriodicCount(maxPeriodicCount)
, m_interval_sec(interval_sec)
, m_interval_nsec(interval_nsec)
@ -160,6 +163,32 @@ private:
TS_ASSERT_EQUALS( t.m_counter, 100 );
}
void testCustomSignal( void )
{
TEST_HEADER;
int customSignal = SIGRTMIN;
// the main thread shall ignore the customSignal
sigset_t set;
sigemptyset( &set );
sigaddset( &set, customSignal );
sigprocmask( SIG_BLOCK, &set, NULL);
DummyTimerThread t( 5, customSignal );
t.start();
// timespec ts = { 4, 0 };
// nanosleep( &ts , 0 );
sleep(4);
t.join();
TS_ASSERT_EQUALS( t.m_counter, 100 );
sigprocmask( SIG_UNBLOCK, &set, NULL );
}
void testTimerThreadHighFreq( void )
{
TEST_HEADER;
@ -173,6 +202,7 @@ private:
int nano = 1000000000; // 10^9
int freq = 80000;
DummyTimerThread t(INT_MAX - 1,
SIGALRM,
1, 0,
0, nano / freq );
@ -185,6 +215,8 @@ private:
// expected 800000 + 100 got 795510
// accurcy: ~ > 99.5%
TS_ASSERT_DELTA ( t.m_counter, 100 + freq * circle, (100 + freq * circle) * 0.995);
sigprocmask( SIG_UNBLOCK, &set, NULL );
}
};

Loading…
Cancel
Save