Real Time Interval TimersReal Time SignalsSIGINFO_TstructurePOSIX:RTS signal queueingSend a queued signal to a processSlide 6POSIX:TMR Interval Timerstimer_createtimer_deleteP328 Display Message every 2 secondsSlide 11Slide 12Slide 13Using a POSIX:TMR to time functionUsing a POSIX:TMR to timeTimer Drift, Overruns and Absolute TimeSummary01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved1Real Time Interval TimersCS 241 Lecture 19T: Ch 3, pp 159-183Roy Campbell01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved2Real Time Signals#include <signal.h>Struct sigaction { void (*sa_handler) (int); /* SIG_DFL, SIG_IGN, or pointer to function*/ sigset_t sa_mask; /*additional signals to be blocked */ /* during execution of handler*/ int sa_flags; /* special flags and options*/ void(*sa_sigaction) (int, siginfo_t *, void *); /* realtime handler*//* Handler looks like*/void func(int signo, siginfo_t * info, void *context);01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved3SIGINFO_Tstructureint si_signo; /* signal number */int si_code; /* cause of signal */union sigval si_value; /* signal value*/c union sigval is defined as int sival_int; void *sival_ptr;01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved4POSIX:RTS signal queueing#include <signal.h> int sigqueue(pid_t pid, int signo, const union sigval value);sigqueue extends killMultiple signals created by kill may not be queued but they are if created by sigqueueSigno should be non-zero. If zero, will check for errors – can use this to see if pid valid, see p322SA_SIGINFO is in sa_flags of struct sigaction, thensignal queued otherwise signal sent at least once.01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved5Send a queued signal to a process#include <signal.h>#include <stdio.h>#include <stdlib.h>int main(int argc, char *argv[]) { int pid; int signo; int sval; union sigval value; if (argc != 4) { fprintf(stderr, "Usage: %s pid signal value\n", argv[0]); return 1; }01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved6Send a queued signal to a processpid = atoi(argv[1]); signo = atoi(argv[2]); sval = atoi(argv[3]); fprintf(stderr, "Sending signal %d with value %d to process %d\n", signo, sval, pid); value.sival_int = sval; if (sigqueue(pid, signo, value) == -1) { perror("Failed to send the signal"); return 1; } return 0;}01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved7POSIX:TMR Interval Timersstruct itimerspecstruct timespec it_interval; /* timer period*/struct timespec it_value; /* timer expiration*/timer_create creates timers --- they are NOT inherited on fork!!!01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved8timer_create#include <signal.h>#include <time.h>int timer_create(clockid_t clock_id, struct sigevent *restrict evp, timer_t *restrict timerid);/* evp is signal event generated when timer expires, 0=default*/struct sigevent { int sigev_notify /*notification type*/ int sigev_signo /*signal number*/ union sigval sigev_value; /*signal value*/};Union sigval { int sival_int; void *sival_ptr: };01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved9timer_delete#include <time.h> int timer_delete(timer_t timerid);int timer_getoverrun(timer_t timerid);int timer_gettime(timer_t timerid, struct itimerspec *value);int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved10P328 Display Message every 2 seconds #include <errno.h>#include <signal.h>#include <stdio.h>#include <time.h>#include <unistd.h>#define BILLION 1000000000L#define TIMER_MSG "Received Timer Interrupt\n"/* ARGSUSED */static void interrupt(int signo, siginfo_t *info, void *context) { int errsave; errsave = errno; write(STDOUT_FILENO, TIMER_MSG, sizeof(TIMER_MSG) - 1); errno = errsave;}Define action to do on signal01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved11static int setinterrupt() { struct sigaction act; act.sa_flags = SA_SIGINFO; act.sa_sigaction = interrupt; if ((sigemptyset(&act.sa_mask) == -1) || (sigaction(SIGALRM, &act, NULL) == -1)) return -1; return 0;}Set actions to do for SIGALRM01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved12static int setperiodic(double sec) { timer_t timerid; struct itimerspec value; if (timer_create(CLOCK_REALTIME, NULL, &timerid) == -1) return -1; value.it_interval.tv_sec = (long)sec; value.it_interval.tv_nsec = (sec - value.it_interval.tv_sec)*BILLION; if (value.it_interval.tv_nsec >= BILLION) { value.it_interval.tv_sec++; value.it_interval.tv_nsec -= BILLION; } value.it_value = value.it_interval; return timer_settime(timerid, 0, &value, NULL);}Create an interval timer that creates SIGALM’s01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved13int main(void) { if (setinterrupt() == -1) { perror("Failed to setup SIGALRM handler"); return 1; } if (setperiodic(2.0) == -1) { perror("Failed to setup periodic interrupt"); return 1; } for ( ; ; ) pause();}Pause causes program to sleep for a real-time amount…. Different from asterix program because of real-time01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved14Using a POSIX:TMR to time function#include <stdio.h>#include <time.h>#define MILLION 1000000L#define THOUSAND 1000void function_to_time(void);int main(void); long diftime; struct itmerspec nvalue, ovalue; timer_t timeid; if (timer_create(CLOCK_REALTIME, NULL, &timeid) == -1) { perror(“Failed to create a timer based on CLOCK_REALTIME”); return 1; }01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved15Using a POSIX:TMR to time ovalue.it_interval.tv_sec = 0; ovalue.it_interval.tv_nsec = 0; ovalue.it_value.tv_sec = 0; ovalue.it_value.tv_nsec = 0; if (timer_settime(timeid, 0, &ovalue, NULL) == -1) { perror(“Failed to set interval timer”); return 1; }function_to_time(); /* timed code goes here */if (timer_gettime(timeid, 0, &nvalue) == -1) { perror(“Failed to get interval timer value”); return 1; }diftime = MILLION *(ovalue.it_value.tv_sec – nvalue.it_value.tv_sec) + (ovalue.it_value.tv_nsec – nvalue.it_value.it.tv_nsec)/THOUSAND;printf(“The function_to_time …..01/13/19 CS241 © 2005 Roy Campbell, All Rights Reserved16Timer Drift, Overruns and Absolute TimeTimer drift caused by overhead in setting timerUse TIMER_ABSOLUTE flag to indicate compensating for overhead
View Full Document