i want interrupted @ frequencies powers of ten, enabling interrupts /dev/rtc isn't ideal. i'd sleep 1 millisecond or 250 microseconds between interrupts.
enabling periodic interrupts /dev/hpet works pretty well, doesn't seem work on machines. can't use on machines don't have hpet. can't working on machines have hpet available clocksource either. example, on core 2 quad, example program included in kernel documentation fails @ hpet_ie_on when set poll.
it nicer use itimer interface provided linux instead of interfacing hardware device driver directly. , on systems, itimer provides periodic interrupts more stable on time. is, since hpet can't interrupt @ frequency want, interrupts start drift wall time. i'm seeing systems sleep way longer (10+ milliseconds) should using itimer.
here's test program using itimer interrupts. on systems print out 1 warning that's slept 100 microseconds or on target time. on others, print out batches of warning slept 10+ milliseconds on target time. compile -lrt , run sudo chrt -f 50 [name]
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <error.h> #include <errno.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/time.h> #include <time.h> #include <signal.h> #include <fcntl.h> #define ns_per_second 1000000000ll #define timespec_to_ns( atime ) ( ( ns_per_second * ( ( long long int ) atime.tv_sec ) ) \ + atime.tv_nsec ) int main() { // block alarm signal, waited on explicitly sigset_t lalarm; sigemptyset( &lalarm ); sigaddset( &lalarm, sigalrm ); sigprocmask( sig_block, &lalarm, null ); // set periodic interrupt timer struct itimerval ltimer; int lreceivedsignal = 0; ltimer.it_value.tv_sec = 0; ltimer.it_value.tv_usec = 250; ltimer.it_interval = ltimer.it_value; // start timer if ( setitimer( itimer_real, <imer, null ) != 0 ) { error( exit_failure, errno, "could not start interval timer" ); } struct timespec llasttime; struct timespec lcurrenttime; clock_gettime( clock_realtime, &llasttime ); while ( 1 ) { //periodic wait if ( sigwait( &lalarm, &lreceivedsignal ) != 0 ) { error( exit_failure, errno, "failed wait next clock tick" ); } clock_gettime( clock_realtime, &lcurrenttime ); long long int ldifference = ( timespec_to_ns( lcurrenttime ) - timespec_to_ns( llasttime ) ); if ( ldifference > 300000 ) { fprintf( stderr, "waited long: %lld\n", ldifference ); } llasttime = lcurrenttime; } return 0; }
i've had same problem bare setitimer() setup. problem process scheduled sched_other policy on static priority level 0 default. means you're in pool other processes, , dynamic priorities decide. moment there system load, latencies.
the solution use sched_setscheduler() system call, increase static priority @ least one, , specify sched_fifo policy. causes dramatic improvement.
#include <sched.h> ... int main(int argc, char *argv[]) { ... struct sched_param schedp; schedp.sched_priority = 1; sched_setscheduler(0, sched_fifo, &schedp); ... }
you have run root able this. alternative use chrt program same, must know pid of rt process.
sudo chrt -f -p 1 <pid>
see blog post here.
Comments
Post a Comment