summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/timers/posix_timers.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests/timers/posix_timers.c')
-rw-r--r--tools/testing/selftests/timers/posix_timers.c89
1 files changed, 47 insertions, 42 deletions
diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c
index 38512623622a..a92d4b957747 100644
--- a/tools/testing/selftests/timers/posix_timers.c
+++ b/tools/testing/selftests/timers/posix_timers.c
@@ -16,10 +16,10 @@
#include <string.h>
#include <unistd.h>
#include <time.h>
-#include <include/vdso/time64.h>
#include <pthread.h>
#include <stdbool.h>
+#include "clock-helpers.h"
#include "kselftest.h"
#define DELAY 2
@@ -78,19 +78,25 @@ static void sig_handler(int nr)
done = 1;
}
+static inline int64_t calcdiff_ns(struct timespec t1, struct timespec t2)
+{
+ int64_t diff;
+
+ diff = NSEC_PER_SEC * (int64_t)((int) t1.tv_sec - (int) t2.tv_sec);
+ diff += ((int) t1.tv_nsec - (int) t2.tv_nsec);
+ return diff;
+}
+
/*
* Check the expected timer expiration matches the GTOD elapsed delta since
* we armed the timer. Keep a 0.5 sec error margin due to various jitter.
*/
-static int check_diff(struct timeval start, struct timeval end)
+static int check_diff(struct timespec start, struct timespec end)
{
- long long diff;
-
- diff = end.tv_usec - start.tv_usec;
- diff += (end.tv_sec - start.tv_sec) * USEC_PER_SEC;
+ long long diff = calcdiff_ns(end, start);
- if (llabs(diff - DELAY * USEC_PER_SEC) > USEC_PER_SEC / 2) {
- printf("Diff too high: %lld..", diff);
+ if (llabs(diff - DELAY * NSEC_PER_SEC) > NSEC_PER_SEC / 2) {
+ printf("Diff too high: %lld ns..", diff);
return -1;
}
@@ -99,22 +105,25 @@ static int check_diff(struct timeval start, struct timeval end)
static void check_itimer(int which, const char *name)
{
- struct timeval start, end;
+ struct timespec start, end;
struct itimerval val = {
.it_value.tv_sec = DELAY,
};
+ int clock_id = CLOCK_REALTIME;
done = 0;
if (which == ITIMER_VIRTUAL)
signal(SIGVTALRM, sig_handler);
- else if (which == ITIMER_PROF)
+ else if (which == ITIMER_PROF) {
+ clock_id = CLOCK_THREAD_CPUTIME_ID;
signal(SIGPROF, sig_handler);
+ }
else if (which == ITIMER_REAL)
signal(SIGALRM, sig_handler);
- if (gettimeofday(&start, NULL) < 0)
- fatal_error(name, "gettimeofday()");
+ if (clock_gettime(clock_id, &start))
+ fatal_error(name, "clock_gettime()");
if (setitimer(which, &val, NULL) < 0)
fatal_error(name, "setitimer()");
@@ -126,18 +135,20 @@ static void check_itimer(int which, const char *name)
else if (which == ITIMER_REAL)
idle_loop();
- if (gettimeofday(&end, NULL) < 0)
- fatal_error(name, "gettimeofday()");
+ if (clock_gettime(clock_id, &end))
+ fatal_error(name, "clock_gettime()");
ksft_test_result(check_diff(start, end) == 0, "%s\n", name);
}
-static void check_timer_create(int which, const char *name)
+static void check_timer_create(int which)
{
- struct timeval start, end;
+ const char *name = clock_name(which);
+ struct timespec start, end;
struct itimerspec val = {
.it_value.tv_sec = DELAY,
};
+ int clock_id = CLOCK_REALTIME;
timer_t id;
done = 0;
@@ -148,16 +159,16 @@ static void check_timer_create(int which, const char *name)
if (signal(SIGALRM, sig_handler) == SIG_ERR)
fatal_error(name, "signal()");
- if (gettimeofday(&start, NULL) < 0)
- fatal_error(name, "gettimeofday()");
+ if (clock_gettime(clock_id, &start))
+ fatal_error(name, "clock_gettime()");
if (timer_settime(id, 0, &val, NULL) < 0)
fatal_error(name, "timer_settime()");
user_loop();
- if (gettimeofday(&end, NULL) < 0)
- fatal_error(name, "gettimeofday()");
+ if (clock_gettime(clock_id, &end))
+ fatal_error(name, "clock_gettime()");
ksft_test_result(check_diff(start, end) == 0,
"timer_create() per %s\n", name);
@@ -445,17 +456,9 @@ static void check_delete(void)
ksft_test_result(!tsig.signals, "check_delete\n");
}
-static inline int64_t calcdiff_ns(struct timespec t1, struct timespec t2)
-{
- int64_t diff;
-
- diff = NSEC_PER_SEC * (int64_t)((int) t1.tv_sec - (int) t2.tv_sec);
- diff += ((int) t1.tv_nsec - (int) t2.tv_nsec);
- return diff;
-}
-
-static void check_sigev_none(int which, const char *name)
+static void check_sigev_none(int which)
{
+ const char *name = clock_name(which);
struct timespec start, now;
struct itimerspec its;
struct sigevent sev;
@@ -492,8 +495,9 @@ static void check_sigev_none(int which, const char *name)
"check_sigev_none %s\n", name);
}
-static void check_gettime(int which, const char *name)
+static void check_gettime(int which)
{
+ const char *name = clock_name(which);
struct itimerspec its, prev;
struct timespec start, now;
struct sigevent sev;
@@ -545,8 +549,9 @@ static void check_gettime(int which, const char *name)
ksft_test_result(wraps > 1, "check_gettime %s\n", name);
}
-static void check_overrun(int which, const char *name)
+static void check_overrun(int which)
{
+ const char *name = clock_name(which);
struct timespec start, now;
struct tmrsig tsig = { };
struct itimerspec its;
@@ -688,7 +693,7 @@ int main(int argc, char **argv)
check_itimer(ITIMER_VIRTUAL, "ITIMER_VIRTUAL");
check_itimer(ITIMER_PROF, "ITIMER_PROF");
check_itimer(ITIMER_REAL, "ITIMER_REAL");
- check_timer_create(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
+ check_timer_create(CLOCK_THREAD_CPUTIME_ID);
/*
* It's unfortunately hard to reliably test a timer expiration
@@ -699,7 +704,7 @@ int main(int argc, char **argv)
* to ensure true parallelism. So test only one thread until we
* find a better solution.
*/
- check_timer_create(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
+ check_timer_create(CLOCK_PROCESS_CPUTIME_ID);
check_timer_distribution();
if (run_sig_ign_tests) {
@@ -707,18 +712,18 @@ int main(int argc, char **argv)
check_sig_ign(1);
check_rearm();
check_delete();
- check_sigev_none(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
- check_sigev_none(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
- check_gettime(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
- check_gettime(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
- check_gettime(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
+ check_sigev_none(CLOCK_MONOTONIC);
+ check_sigev_none(CLOCK_PROCESS_CPUTIME_ID);
+ check_gettime(CLOCK_MONOTONIC);
+ check_gettime(CLOCK_PROCESS_CPUTIME_ID);
+ check_gettime(CLOCK_THREAD_CPUTIME_ID);
} else {
ksft_print_msg("Skipping SIG_IGN tests on kernel < 6.13\n");
}
- check_overrun(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
- check_overrun(CLOCK_PROCESS_CPUTIME_ID, "CLOCK_PROCESS_CPUTIME_ID");
- check_overrun(CLOCK_THREAD_CPUTIME_ID, "CLOCK_THREAD_CPUTIME_ID");
+ check_overrun(CLOCK_MONOTONIC);
+ check_overrun(CLOCK_PROCESS_CPUTIME_ID);
+ check_overrun(CLOCK_THREAD_CPUTIME_ID);
ksft_finished();
}