diff options
author | Greg Hackmann <ghackmann@google.com> | 2017-07-25 14:36:26 -0700 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2017-08-17 12:14:58 -0700 |
commit | 28be3f8f48cfb3cf024860f042d424cd4824f5f7 (patch) | |
tree | 47d9c085f9218d2cce26962ed724a10445cdca0e /tools | |
parent | a524b1184b8e86141d689fa78ad150fbf2db9b4c (diff) | |
download | linux-stable-28be3f8f48cfb3cf024860f042d424cd4824f5f7.tar.gz linux-stable-28be3f8f48cfb3cf024860f042d424cd4824f5f7.tar.bz2 linux-stable-28be3f8f48cfb3cf024860f042d424cd4824f5f7.zip |
kselftests: timers: set-timer-lat: Add one-shot timer test cases
These testcases are motivated by a recent alarmtimer regression, which
caused one-shot CLOCK_{BOOTTIME,REALTIME}_ALARM timers to become
periodic timers.
The new testcases are very similar to the existing testcases for
repeating timers. But rather than waiting for 5 alarms, they wait for 5
seconds and verify that the alarm fired exactly once.
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-kselftest@vger.kernel.org
Signed-off-by: Greg Hackmann <ghackmann@google.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/testing/selftests/timers/set-timer-lat.c | 86 |
1 files changed, 73 insertions, 13 deletions
diff --git a/tools/testing/selftests/timers/set-timer-lat.c b/tools/testing/selftests/timers/set-timer-lat.c index 10c2e18737c0..15434da23b04 100644 --- a/tools/testing/selftests/timers/set-timer-lat.c +++ b/tools/testing/selftests/timers/set-timer-lat.c @@ -20,6 +20,7 @@ */ +#include <errno.h> #include <stdio.h> #include <unistd.h> #include <time.h> @@ -122,17 +123,17 @@ void sigalarm(int signo) max_latency_ns = delta_ns; } -void describe_timer(int flags) +void describe_timer(int flags, int interval) { - printf("%-22s %s ", + printf("%-22s %s %s ", clockstring(clock_id), - flags ? "ABSTIME":"RELTIME"); + flags ? "ABSTIME":"RELTIME", + interval ? "PERIODIC":"ONE-SHOT"); } -int do_timer(int clock_id, int flags) +int setup_timer(int clock_id, int flags, int interval, timer_t *tm1) { struct sigevent se; - timer_t tm1; struct itimerspec its1, its2; int err; @@ -146,7 +147,7 @@ int do_timer(int clock_id, int flags) alarmcount = 0; timer_fired_early = 0; - err = timer_create(clock_id, &se, &tm1); + err = timer_create(clock_id, &se, tm1); if (err) { if ((clock_id == CLOCK_REALTIME_ALARM) || (clock_id == CLOCK_BOOTTIME_ALARM)) { @@ -167,19 +168,23 @@ int do_timer(int clock_id, int flags) its1.it_value.tv_sec = TIMER_SECS; its1.it_value.tv_nsec = 0; } - its1.it_interval.tv_sec = TIMER_SECS; + its1.it_interval.tv_sec = interval; its1.it_interval.tv_nsec = 0; - err = timer_settime(tm1, flags, &its1, &its2); + err = timer_settime(*tm1, flags, &its1, &its2); if (err) { printf("%s - timer_settime() failed\n", clockstring(clock_id)); return -1; } - while (alarmcount < 5) - sleep(1); + return 0; +} - describe_timer(flags); +int check_timer_latency(int flags, int interval) +{ + int err = 0; + + describe_timer(flags, interval); printf("timer fired early: %7d : ", timer_fired_early); if (!timer_fired_early) { printf("[OK]\n"); @@ -188,10 +193,9 @@ int do_timer(int clock_id, int flags) err = -1; } - describe_timer(flags); + describe_timer(flags, interval); printf("max latency: %10lld ns : ", max_latency_ns); - timer_delete(tm1); if (max_latency_ns < UNRESONABLE_LATENCY) { printf("[OK]\n"); } else { @@ -201,6 +205,60 @@ int do_timer(int clock_id, int flags) return err; } +int check_alarmcount(int flags, int interval) +{ + describe_timer(flags, interval); + printf("count: %19d : ", alarmcount); + if (alarmcount == 1) { + printf("[OK]\n"); + return 0; + } + printf("[FAILED]\n"); + return -1; +} + +int do_timer(int clock_id, int flags) +{ + timer_t tm1; + const int interval = TIMER_SECS; + int err; + + err = setup_timer(clock_id, flags, interval, &tm1); + if (err) + return err; + + while (alarmcount < 5) + sleep(1); + + timer_delete(tm1); + return check_timer_latency(flags, interval); +} + +int do_timer_oneshot(int clock_id, int flags) +{ + timer_t tm1; + const int interval = 0; + struct timeval timeout; + fd_set fds; + int err; + + err = setup_timer(clock_id, flags, interval, &tm1); + if (err) + return err; + + memset(&timeout, 0, sizeof(timeout)); + timeout.tv_sec = 5; + FD_ZERO(&fds); + do { + err = select(FD_SETSIZE, &fds, NULL, NULL, &timeout); + } while (err == -1 && errno == EINTR); + + timer_delete(tm1); + err = check_timer_latency(flags, interval); + err |= check_alarmcount(flags, interval); + return err; +} + int main(void) { struct sigaction act; @@ -226,6 +284,8 @@ int main(void) ret |= do_timer(clock_id, TIMER_ABSTIME); ret |= do_timer(clock_id, 0); + ret |= do_timer_oneshot(clock_id, TIMER_ABSTIME); + ret |= do_timer_oneshot(clock_id, 0); } if (ret) return ksft_exit_fail(); |