summaryrefslogtreecommitdiffstats
path: root/src/kernel/tests/lib/tst_wallclock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/tests/lib/tst_wallclock.c')
-rw-r--r--src/kernel/tests/lib/tst_wallclock.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/kernel/tests/lib/tst_wallclock.c b/src/kernel/tests/lib/tst_wallclock.c
new file mode 100644
index 0000000..282d6ad
--- /dev/null
+++ b/src/kernel/tests/lib/tst_wallclock.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2019 Linaro Limited. All rights reserved.
+ * Author: Rafael David Tinoco <rafael.tinoco@linaro.org>
+ */
+
+#include <errno.h>
+
+#define TST_NO_DEFAULT_MAIN
+
+#include "tst_test.h"
+#include "tst_timer.h"
+#include "tst_clocks.h"
+#include "tst_wallclock.h"
+#include "lapi/posix_clocks.h"
+
+static struct timespec real_begin, mono_begin;
+
+static int clock_saved;
+
+void tst_wallclock_save(void)
+{
+ /* save initial monotonic time to restore it when needed */
+
+ if (tst_clock_gettime(CLOCK_REALTIME, &real_begin))
+ tst_brk(TBROK | TERRNO, "tst_clock_gettime() realtime failed");
+
+ if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_begin)) {
+ if (errno == EINVAL) {
+ tst_brk(TCONF | TERRNO,
+ "tst_clock_gettime() didn't support CLOCK_MONOTONIC_RAW");
+ }
+
+ tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
+ }
+
+ clock_saved = 1;
+}
+
+void tst_wallclock_restore(void)
+{
+ static struct timespec mono_end, elapsed, adjust;
+
+ if (!clock_saved)
+ return;
+
+ clock_saved = 0;
+
+ if (tst_clock_gettime(CLOCK_MONOTONIC_RAW, &mono_end))
+ tst_brk(TBROK | TERRNO, "tst_clock_gettime() monotonic failed");
+
+ elapsed = tst_timespec_diff(mono_end, mono_begin);
+
+ adjust = tst_timespec_add(real_begin, elapsed);
+
+ /* restore realtime clock based on monotonic delta */
+
+ if (tst_clock_settime(CLOCK_REALTIME, &adjust))
+ tst_brk(TBROK | TERRNO, "tst_clock_settime() realtime failed");
+}