1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) 2017 Cyril Hrubis <chrubis@suse.cz>
4 */
5
6 #include <time.h>
7
8 #define TST_NO_DEFAULT_MAIN
9 #include "tst_test.h"
10 #include "tst_timer.h"
11 #include "tst_clocks.h"
12 #include "lapi/syscalls.h"
13 #include "lapi/posix_clocks.h"
14
15 typedef int (*mysyscall)(clockid_t clk_id, void *ts);
16
syscall_supported_by_kernel(long sysnr)17 int syscall_supported_by_kernel(long sysnr)
18 {
19 int ret;
20
21 ret = syscall(sysnr, 0, NULL);
22 if (ret == -1 && errno == ENOSYS)
23 return 0;
24
25 return 1;
26 }
27
tst_clock_getres(clockid_t clk_id,struct timespec * res)28 int tst_clock_getres(clockid_t clk_id, struct timespec *res)
29 {
30 static struct tst_ts tts = { 0, };
31 static mysyscall func;
32 int ret;
33
34 #if (__NR_clock_getres_time64 != __LTP__NR_INVALID_SYSCALL)
35 if (!func && syscall_supported_by_kernel(__NR_clock_getres_time64)) {
36 func = sys_clock_getres64;
37 tts.type = TST_KERN_TIMESPEC;
38 }
39 #endif
40
41 if (!func && syscall_supported_by_kernel(__NR_clock_getres)) {
42 func = sys_clock_getres;
43 tts.type = TST_KERN_OLD_TIMESPEC;
44 }
45
46 if (!func) {
47 tst_res(TCONF, "clock_getres() not available");
48 errno = ENOSYS;
49 return -1;
50 }
51
52 ret = func(clk_id, tst_ts_get(&tts));
53 res->tv_sec = tst_ts_get_sec(tts);
54 res->tv_nsec = tst_ts_get_nsec(tts);
55 return ret;
56 }
57
tst_clock_gettime(clockid_t clk_id,struct timespec * ts)58 int tst_clock_gettime(clockid_t clk_id, struct timespec *ts)
59 {
60 static struct tst_ts tts = { 0, };
61 static mysyscall func;
62 int ret;
63
64 #if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL)
65 if (!func && syscall_supported_by_kernel(__NR_clock_gettime64)) {
66 func = sys_clock_gettime64;
67 tts.type = TST_KERN_TIMESPEC;
68 }
69 #endif
70
71 if (!func && syscall_supported_by_kernel(__NR_clock_gettime)) {
72 func = sys_clock_gettime;
73 tts.type = TST_KERN_OLD_TIMESPEC;
74 }
75
76 if (!func) {
77 tst_res(TCONF, "clock_gettime() not available");
78 errno = ENOSYS;
79 return -1;
80 }
81
82 ret = func(clk_id, tst_ts_get(&tts));
83 ts->tv_sec = tst_ts_get_sec(tts);
84 ts->tv_nsec = tst_ts_get_nsec(tts);
85 return ret;
86 }
87
tst_clock_settime(clockid_t clk_id,struct timespec * ts)88 int tst_clock_settime(clockid_t clk_id, struct timespec *ts)
89 {
90 static struct tst_ts tts = { 0, };
91 static mysyscall func;
92
93 #if (__NR_clock_settime64 != __LTP__NR_INVALID_SYSCALL)
94 if (!func && syscall_supported_by_kernel(__NR_clock_settime64)) {
95 func = sys_clock_settime64;
96 tts.type = TST_KERN_TIMESPEC;
97 }
98 #endif
99
100 if (!func && syscall_supported_by_kernel(__NR_clock_settime)) {
101 func = sys_clock_settime;
102 tts.type = TST_KERN_OLD_TIMESPEC;
103 }
104
105 if (!func) {
106 tst_res(TCONF, "clock_settime() not available");
107 errno = ENOSYS;
108 return -1;
109 }
110
111 tst_ts_set_sec(&tts, ts->tv_sec);
112 tst_ts_set_nsec(&tts, ts->tv_nsec);
113 return func(clk_id, tst_ts_get(&tts));
114 }
115
tst_clock_name(clockid_t clk_id)116 const char *tst_clock_name(clockid_t clk_id)
117 {
118 switch (clk_id) {
119 case CLOCK_REALTIME:
120 return "CLOCK_REALTIME";
121 case CLOCK_MONOTONIC:
122 return "CLOCK_MONOTONIC";
123 case CLOCK_PROCESS_CPUTIME_ID:
124 return "CLOCK_PROCESS_CPUTIME_ID";
125 case CLOCK_THREAD_CPUTIME_ID:
126 return "CLOCK_THREAD_CPUTIME_ID";
127 case CLOCK_MONOTONIC_RAW:
128 return "CLOCK_MONOTONIC_RAW";
129 case CLOCK_REALTIME_COARSE:
130 return "CLOCK_REALTIME_COARSE";
131 case CLOCK_MONOTONIC_COARSE:
132 return "CLOCK_MONOTONIC_COARSE";
133 case CLOCK_BOOTTIME:
134 return "CLOCK_BOOTTIME";
135 case CLOCK_REALTIME_ALARM:
136 return "CLOCK_REALTIME_ALARM";
137 case CLOCK_BOOTTIME_ALARM:
138 return "CLOCK_BOOTTIME_ALARM";
139 case CLOCK_TAI:
140 return "CLOCK_TAI";
141 default:
142 return "INVALID/UNKNOWN CLOCK";
143 }
144 }
145
tst_get_fs_timestamp(void)146 time_t tst_get_fs_timestamp(void)
147 {
148 struct timespec ts;
149 int ret;
150
151 ret = tst_clock_gettime(CLOCK_REALTIME_COARSE, &ts);
152
153 if (ret < 0)
154 tst_brk(TBROK | TERRNO, "clock_gettime(CLOCK_REALTIME_COARSE)");
155
156 return ts.tv_sec;
157 }
158