#include #include #include #include #include #include #include #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) const int test_periods_us[] = { 10000, 9998, 1000, 11111, 21315, 1500, 15000, 50000, 500, }; volatile int prof_counter; void handler(int signr) { prof_counter++; } #define CPUCLOCK_PROF 0 #define CPUCLOCK_VIRT 1 #define CPUCLOCK_SCHED 2 #define MAKE_PROCESS_CPUCLOCK(pid, clock) \ ((~(clockid_t) (pid) << 3) | (clockid_t) (clock)) #define CLK_PROF MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_PROF) #define CLK_VIRT MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_VIRT) #define CLK_SCHED MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED) void test_func(void) { int i = 0; int count = 0; for(i=0; i<2000000000; i++) count++; } double timeval_diff(const struct timeval *start, const struct timeval *end) { return (end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec)/1000000.0; } void measure_itimer_error(int period_us, clockid_t clk_id) { struct sigaction act; struct timeval start, end; struct sigevent evt; double real_time, counted_time; timer_t tid; prof_counter = 0; struct timespec period_ts = { .tv_sec = 0, .tv_nsec = period_us * 1000, }; struct itimerspec timer_spec = { .it_interval = period_ts, .it_value = period_ts }; act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; if (sigaction(SIGPROF, &act, NULL) < 0) { printf("sigaction failed\n"); exit(1); } memset(&evt, 0, sizeof(evt)); evt.sigev_notify = SIGEV_SIGNAL; evt.sigev_signo = SIGPROF; if (timer_create(clk_id, &evt, &tid) < 0) { perror("timer_create"); exit(1); } if (timer_settime(tid, 0, &timer_spec, NULL) < 0) { perror("timer_settime"); exit(1); } /* run a busy loop and measure it */ gettimeofday(&start, NULL); test_func(); gettimeofday(&end, NULL); /* disable the timer */ memset(&timer_spec, 0, sizeof(timer_spec)); if (timer_settime(tid, 0, &timer_spec, NULL) < 0) { perror("timer_settime"); exit(1); } if (timer_delete(tid) < 0) { perror("timer_delete"); exit(1); } counted_time = prof_counter * period_us / 1000000.0; real_time = timeval_diff(&start, &end); printf("Period %d:\tcounted time %.2f , real time %.2f , error %.1f %%\n", period_us, counted_time, real_time, (counted_time/real_time - 1.0)*100.0); } int main() { int i; printf("CLK_PROF\n"); for (i=0; i