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