1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2019 Linaro Limited. All rights reserved.
4 * Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
5 */
6
7 #include <errno.h>
8
9 #define TST_NO_DEFAULT_MAIN
10
11 #include "tst_test.h"
12 #include "tst_timer.h"
13 #include "tst_clocks.h"
14 #include "tst_wallclock.h"
15 #include "lapi/posix_clocks.h"
16
17 static struct timespec real_begin, mono_begin;
18
19 static int clock_saved;
20
tst_wallclock_save(void)21 void tst_wallclock_save(void)
22 {
23 /* save initial monotonic time to restore it when needed */
24
25 if (tst_clock_gettime(CLOCK_REALTIME, &real_begin))
26 tst_brk(TBROK | TERRNO, "tst_clock_gettime() realtime failed");
27
28 if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin)) {
29 if (errno == EINVAL) {
30 tst_brk(TCONF | TERRNO,
31 "tst_clock_gettime() didn't support CLOCK_MONOTONIC_RAW");
32 }
33
34 tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
35 }
36
37 clock_saved = 1;
38 }
39
tst_wallclock_restore(void)40 void tst_wallclock_restore(void)
41 {
42 static struct timespec mono_end, elapsed, adjust;
43
44 if (!clock_saved)
45 return;
46
47 clock_saved = 0;
48
49 if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end))
50 tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
51
52 elapsed = tst_timespec_diff(mono_end, mono_begin);
53
54 adjust = tst_timespec_add(real_begin, elapsed);
55
56 /* restore realtime clock based on monotonic delta */
57
58 if (tst_clock_settime(CLOCK_REALTIME, &adjust))
59 tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed");
60 }
61