#include #include #include #include #include #include struct test_case { clockid_t clock; timer_t timer_id; int flags; struct itimerspec end; int error; int result_ms; // is the result shall be altered by setting the system clock? int is_altered; }; static struct test_case tests[] = { { .clock = CLOCK_REALTIME, .flags = TIMER_ABSTIME, .is_altered = 1 }, { .clock = CLOCK_MONOTONIC, .flags = TIMER_ABSTIME}, { .clock = CLOCK_REALTIME}, { .clock = CLOCK_MONOTONIC} }; static const int num_tests = sizeof(tests)/sizeof(tests[0]); void shift_time(int t) { int error = 0; struct timespec tp; error |= clock_gettime(CLOCK_REALTIME, &tp); if (!error) { tp.tv_sec += t; error |= clock_settime(CLOCK_REALTIME, &tp); } if (error) { printf("Couldn't set the system clock.\n" "(Please try again with the necessary administrative rights.)\n"); exit(1); } } int main() { // Alter the system clock // (will be set back to the correct value later) shift_time(-2); // Setup for(int i=0; i < num_tests; ++i) { struct sigevent evt = { .sigev_notify = SIGEV_NONE }; tests[i].error |= timer_create(tests[i].clock, &evt, &tests[i].timer_id); if (tests[i].flags & TIMER_ABSTIME) { tests[i].error |= clock_gettime(tests[i].clock, &tests[i].end.it_value); } tests[i].end.it_value.tv_sec += 5; tests[i].error |= timer_settime(tests[i].timer_id, tests[i].flags, &tests[i].end, NULL); } sleep(1); // Shift time forward // (correcting the system time as a result) shift_time(2); // get remaining times for(int i=0; i < num_tests; ++i) { struct itimerspec remaining; tests[i].error |= timer_gettime(tests[i].timer_id, &remaining); tests[i].result_ms = remaining.it_value.tv_sec*1000; tests[i].result_ms += (remaining.it_value.tv_nsec+500*1000)/(1000*1000); } // Report results int overall_ok = 1; for(int i=0; i < num_tests; ++i) { if (tests[i].clock == CLOCK_REALTIME) { printf("CLOCK_REALTIME, "); } if (tests[i].clock == CLOCK_MONOTONIC) { printf("CLOCK_MONOTONIC, "); } if (tests[i].flags & TIMER_ABSTIME) { printf("absolute: "); } else { printf("relative: "); } if (tests[i].error) { overall_ok = 0; puts("ERROR"); continue; } printf("%d ms, ", tests[i].result_ms); int expected_ms = tests[i].is_altered ? 2000 : 4000; if (abs(tests[i].result_ms - expected_ms) < 500) { puts("OK"); } else { puts("Failed"); overall_ok = 0; } } printf("\nResult: %s\n", overall_ok ? "OK" : "Failed"); return 0; }