1 /*
2 * Copyright (c) 2018 Intel Corporation
3 * Copyright (c) 2018 Friedt Professional Engineering Services, Inc
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <errno.h>
9 #include <time.h>
10
11 #include <zephyr/kernel.h>
12 #include <zephyr/posix/sys/time.h>
13 #include <zephyr/posix/unistd.h>
14 #include <zephyr/sys/clock.h>
15
clock_gettime(clockid_t clock_id,struct timespec * ts)16 int clock_gettime(clockid_t clock_id, struct timespec *ts)
17 {
18 int ret;
19
20 ret = sys_clock_gettime(sys_clock_from_clockid((int)clock_id), ts);
21 if (ret < 0) {
22 errno = -ret;
23 return -1;
24 }
25
26 return 0;
27 }
28
clock_getres(clockid_t clock_id,struct timespec * res)29 int clock_getres(clockid_t clock_id, struct timespec *res)
30 {
31 BUILD_ASSERT(CONFIG_SYS_CLOCK_TICKS_PER_SEC > 0 &&
32 CONFIG_SYS_CLOCK_TICKS_PER_SEC <= NSEC_PER_SEC,
33 "CONFIG_SYS_CLOCK_TICKS_PER_SEC must be > 0 and <= NSEC_PER_SEC");
34
35 if (!(clock_id == CLOCK_MONOTONIC || clock_id == CLOCK_REALTIME ||
36 clock_id == CLOCK_PROCESS_CPUTIME_ID)) {
37 errno = EINVAL;
38 return -1;
39 }
40
41 if (res != NULL) {
42 *res = (struct timespec){
43 .tv_sec = 0,
44 .tv_nsec = NSEC_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC,
45 };
46 }
47
48 return 0;
49 }
50
51 /**
52 * @brief Set the time of the specified clock.
53 *
54 * See IEEE 1003.1.
55 *
56 * Note that only the `CLOCK_REALTIME` clock can be set using this
57 * call.
58 */
clock_settime(clockid_t clock_id,const struct timespec * tp)59 int clock_settime(clockid_t clock_id, const struct timespec *tp)
60 {
61 int ret;
62
63 ret = sys_clock_settime(sys_clock_from_clockid((int)clock_id), tp);
64 if (ret < 0) {
65 errno = -ret;
66 return -1;
67 }
68
69 return 0;
70 }
71
72 /*
73 * Note: usleep() was removed in Issue 7.
74 *
75 * It is kept here for compatibility purposes.
76 *
77 * For more information, please see
78 * https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap01.html
79 * https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap03.html
80 */
usleep(useconds_t useconds)81 int usleep(useconds_t useconds)
82 {
83 int32_t rem;
84
85 if (useconds >= USEC_PER_SEC) {
86 errno = EINVAL;
87 return -1;
88 }
89
90 rem = k_usleep(useconds);
91 __ASSERT_NO_MSG(rem >= 0);
92 if (rem > 0) {
93 /* sleep was interrupted by a call to k_wakeup() */
94 errno = EINTR;
95 return -1;
96 }
97
98 return 0;
99 }
100
nanosleep(const struct timespec * rqtp,struct timespec * rmtp)101 int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
102 {
103 int ret;
104
105 if (rqtp == NULL) {
106 errno = EFAULT;
107 return -1;
108 }
109
110 ret = sys_clock_nanosleep(SYS_CLOCK_REALTIME, 0, rqtp, rmtp);
111 if (ret < 0) {
112 errno = -ret;
113 return -1;
114 }
115
116 return 0;
117 }
118
clock_getcpuclockid(pid_t pid,clockid_t * clock_id)119 int clock_getcpuclockid(pid_t pid, clockid_t *clock_id)
120 {
121 /* We don't allow any process ID but our own. */
122 if (pid != 0 && pid != getpid()) {
123 return EPERM;
124 }
125
126 *clock_id = CLOCK_PROCESS_CPUTIME_ID;
127
128 return 0;
129 }
130