I was trying to create a timer that depends on the system clock. That means when the system time changes it should affect the expiry of this timer too. So I thought, creating a timer based on CLOCK_REALTIME should do the trick. But when this timer is armed to expire after 60 sec and when I advanced the system clock by 32 sec (using date command), the timer expired exactly after 60 sec. It didn't expire 32 sec earlier.
So I calculated the time elapsed for CLOCK_REALTIME and CLOCK_MONOTONIC clocks between the 2 timer expiry. It showed 92 secs for CLOCK_REALTIME and 60 sec for CLOCK_MONOTONIC, which made me surprised that a timer based on CLOCK_REALTIME didn't look for system clock changes. Can anyone please explain this behavior?
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
timer_t timerID;
struct timespec rt1, rt2, mt1, mt2;
void TimerCalback()
{
clock_gettime(CLOCK_REALTIME, &rt1);
clock_gettime(CLOCK_MONOTONIC, &mt1);
printf("%lu sec elapsed for CLOCK_REALTIME\n", rt1.tv_sec - rt2.tv_sec);
printf("%lu sec elapsed for CLOCK_MONOTONIC\n", mt1.tv_sec - mt2.tv_sec);
rt2 = rt1;
mt2 = mt1;
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
printf("REALTIME Timer Expired at %s\n", asctime (timeinfo));
}
void CreateTimer()
{
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = TimerCalback;
sigemptyset(&sa.sa_mask);
sigaction(SIGRTMIN, &sa, NULL);
struct sigevent te;
memset(&te,0,sizeof(struct sigevent));
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = SIGRTMIN;
te.sigev_value.sival_ptr = &timerID;
timer_create(CLOCK_REALTIME, &te, &timerID);
struct itimerspec its;
its.it_value.tv_sec = 1;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 60;
its.it_interval.tv_nsec = 0;
timer_settime(timerID, 0, &its, NULL);
}
void main()
{
CreateTimer();
while(1)
{
usleep(1);
}
}
And I got this output. After the first expiry, I advanced system clock.
$ ./realtimeTimer
1407240463 sec elapsed for CLOCK_REALTIME
17747 sec elapsed for CLOCK_MONOTONIC
REALTIME Timer Expired at Tue Aug 5 17:37:43 2014
92 sec elapsed for CLOCK_REALTIME
60 sec elapsed for CLOCK_MONOTONIC
REALTIME Timer Expired at Tue Aug 5 17:39:15 2014
Later searching on the web, I stumbled upon this man page which tells
All implementations support the system-wide real-time clock, which is identified by CLOCK_REALTIME. Its time represents seconds and nanoseconds since the Epoch. When its time is changed, timers for a relative interval are unaffected, but timers for an absolute point in time are affected.
Can this be the reason for this behavior?
What am I doing wrong/missing here?
Is there any way to make a timer expire at a particular system time?