xref: /linux/tools/include/nolibc/time.h (revision 7fc2cd2e4b398c57c9cf961cfea05eadbf34c05c)
1 /* SPDX-License-Identifier: LGPL-2.1 OR MIT */
2 /*
3  * time function definitions for NOLIBC
4  * Copyright (C) 2017-2022 Willy Tarreau <w@1wt.eu>
5  */
6 
7 /* make sure to include all global symbols */
8 #include "nolibc.h"
9 
10 #ifndef _NOLIBC_TIME_H
11 #define _NOLIBC_TIME_H
12 
13 #include "std.h"
14 #include "arch.h"
15 #include "types.h"
16 #include "sys.h"
17 
18 #include <linux/signal.h>
19 #include <linux/time.h>
20 
21 static __inline__
22 void __nolibc_timespec_user_to_kernel(const struct timespec *ts, struct __kernel_timespec *kts)
23 {
24 	kts->tv_sec = ts->tv_sec;
25 	kts->tv_nsec = ts->tv_nsec;
26 }
27 
28 static __inline__
29 void __nolibc_timespec_kernel_to_user(const struct __kernel_timespec *kts, struct timespec *ts)
30 {
31 	ts->tv_sec = kts->tv_sec;
32 	ts->tv_nsec = kts->tv_nsec;
33 }
34 
35 /*
36  * int clock_getres(clockid_t clockid, struct timespec *res);
37  * int clock_gettime(clockid_t clockid, struct timespec *tp);
38  * int clock_settime(clockid_t clockid, const struct timespec *tp);
39  * int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp,
40  *                     struct timespec *rmtp)
41  */
42 
43 static __attribute__((unused))
44 int sys_clock_getres(clockid_t clockid, struct timespec *res)
45 {
46 #if defined(__NR_clock_getres)
47 	return my_syscall2(__NR_clock_getres, clockid, res);
48 #else
49 	struct __kernel_timespec kres;
50 	int ret;
51 
52 	ret = my_syscall2(__NR_clock_getres_time64, clockid, &kres);
53 	if (res)
54 		__nolibc_timespec_kernel_to_user(&kres, res);
55 	return ret;
56 #endif
57 }
58 
59 static __attribute__((unused))
60 int clock_getres(clockid_t clockid, struct timespec *res)
61 {
62 	return __sysret(sys_clock_getres(clockid, res));
63 }
64 
65 static __attribute__((unused))
66 int sys_clock_gettime(clockid_t clockid, struct timespec *tp)
67 {
68 #if defined(__NR_clock_gettime)
69 	return my_syscall2(__NR_clock_gettime, clockid, tp);
70 #else
71 	struct __kernel_timespec ktp;
72 	int ret;
73 
74 	ret = my_syscall2(__NR_clock_gettime64, clockid, &ktp);
75 	if (tp)
76 		__nolibc_timespec_kernel_to_user(&ktp, tp);
77 	return ret;
78 #endif
79 }
80 
81 static __attribute__((unused))
82 int clock_gettime(clockid_t clockid, struct timespec *tp)
83 {
84 	return __sysret(sys_clock_gettime(clockid, tp));
85 }
86 
87 static __attribute__((unused))
88 int sys_clock_settime(clockid_t clockid, struct timespec *tp)
89 {
90 #if defined(__NR_clock_settime)
91 	return my_syscall2(__NR_clock_settime, clockid, tp);
92 #else
93 	struct __kernel_timespec ktp;
94 
95 	__nolibc_timespec_user_to_kernel(tp, &ktp);
96 	return my_syscall2(__NR_clock_settime64, clockid, &ktp);
97 #endif
98 }
99 
100 static __attribute__((unused))
101 int clock_settime(clockid_t clockid, struct timespec *tp)
102 {
103 	return __sysret(sys_clock_settime(clockid, tp));
104 }
105 
106 static __attribute__((unused))
107 int sys_clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp,
108 			struct timespec *rmtp)
109 {
110 #if defined(__NR_clock_nanosleep)
111 	return my_syscall4(__NR_clock_nanosleep, clockid, flags, rqtp, rmtp);
112 #else
113 	struct __kernel_timespec krqtp, krmtp;
114 	int ret;
115 
116 	__nolibc_timespec_user_to_kernel(rqtp, &krqtp);
117 	ret = my_syscall4(__NR_clock_nanosleep_time64, clockid, flags, &krqtp, &krmtp);
118 	if (rmtp)
119 		__nolibc_timespec_kernel_to_user(&krmtp, rmtp);
120 	return ret;
121 #endif
122 }
123 
124 static __attribute__((unused))
125 int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *rqtp,
126 		    struct timespec *rmtp)
127 {
128 	/* Directly return a positive error number */
129 	return -sys_clock_nanosleep(clockid, flags, rqtp, rmtp);
130 }
131 
132 static __inline__
133 double difftime(time_t time1, time_t time2)
134 {
135 	return time1 - time2;
136 }
137 
138 static __inline__
139 int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
140 {
141 	return __sysret(sys_clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rmtp));
142 }
143 
144 
145 static __attribute__((unused))
146 time_t time(time_t *tptr)
147 {
148 	struct timeval tv;
149 
150 	/* note, cannot fail here */
151 	sys_gettimeofday(&tv, NULL);
152 
153 	if (tptr)
154 		*tptr = tv.tv_sec;
155 	return tv.tv_sec;
156 }
157 
158 
159 /*
160  * int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid);
161  * int timer_gettime(timer_t timerid, struct itimerspec *curr_value);
162  * int timer_settime(timer_t timerid, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
163  */
164 
165 static __attribute__((unused))
166 int sys_timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
167 {
168 	return my_syscall3(__NR_timer_create, clockid, evp, timerid);
169 }
170 
171 static __attribute__((unused))
172 int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
173 {
174 	return __sysret(sys_timer_create(clockid, evp, timerid));
175 }
176 
177 static __attribute__((unused))
178 int sys_timer_delete(timer_t timerid)
179 {
180 	return my_syscall1(__NR_timer_delete, timerid);
181 }
182 
183 static __attribute__((unused))
184 int timer_delete(timer_t timerid)
185 {
186 	return __sysret(sys_timer_delete(timerid));
187 }
188 
189 static __attribute__((unused))
190 int sys_timer_gettime(timer_t timerid, struct itimerspec *curr_value)
191 {
192 #if defined(__NR_timer_gettime)
193 	return my_syscall2(__NR_timer_gettime, timerid, curr_value);
194 #else
195 	struct __kernel_itimerspec kcurr_value;
196 	int ret;
197 
198 	ret = my_syscall2(__NR_timer_gettime64, timerid, &kcurr_value);
199 	__nolibc_timespec_kernel_to_user(&kcurr_value.it_interval, &curr_value->it_interval);
200 	__nolibc_timespec_kernel_to_user(&kcurr_value.it_value, &curr_value->it_value);
201 	return ret;
202 #endif
203 }
204 
205 static __attribute__((unused))
206 int timer_gettime(timer_t timerid, struct itimerspec *curr_value)
207 {
208 	return __sysret(sys_timer_gettime(timerid, curr_value));
209 }
210 
211 static __attribute__((unused))
212 int sys_timer_settime(timer_t timerid, int flags,
213 		      const struct itimerspec *new_value, struct itimerspec *old_value)
214 {
215 #if defined(__NR_timer_settime)
216 	return my_syscall4(__NR_timer_settime, timerid, flags, new_value, old_value);
217 #else
218 	struct __kernel_itimerspec knew_value, kold_value;
219 	int ret;
220 
221 	__nolibc_timespec_user_to_kernel(&new_value->it_value, &knew_value.it_value);
222 	__nolibc_timespec_user_to_kernel(&new_value->it_interval, &knew_value.it_interval);
223 	ret = my_syscall4(__NR_timer_settime64, timerid, flags, &knew_value, &kold_value);
224 	if (old_value) {
225 		__nolibc_timespec_kernel_to_user(&kold_value.it_interval, &old_value->it_interval);
226 		__nolibc_timespec_kernel_to_user(&kold_value.it_value, &old_value->it_value);
227 	}
228 	return ret;
229 #endif
230 }
231 
232 static __attribute__((unused))
233 int timer_settime(timer_t timerid, int flags,
234 		  const struct itimerspec *new_value, struct itimerspec *old_value)
235 {
236 	return __sysret(sys_timer_settime(timerid, flags, new_value, old_value));
237 }
238 
239 #endif /* _NOLIBC_TIME_H */
240