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