1 /*
2 * Copyright (C) 2015-2021 Alibaba Group Holding Limited
3 */
4
5 #include <stdint.h>
6 #include <time.h>
7
8 #include <aos/errno.h>
9 #include <aos/kernel.h>
10
clock_getres(clockid_t clock_id,struct timespec * res)11 int clock_getres(clockid_t clock_id, struct timespec *res)
12 {
13 /* At now, only support CLOCK_REALTIME/CLOCK_MONOTONIC clock. */
14 if (((clock_id != CLOCK_REALTIME) && (clock_id != CLOCK_MONOTONIC)) || (res == NULL)) {
15 errno = EINVAL;
16 return -1;
17 }
18
19 res->tv_sec = 0;
20 res->tv_nsec = 1000000;
21
22 return 0;
23 }
24
clock_gettime(clockid_t clock_id,struct timespec * tp)25 int clock_gettime(clockid_t clock_id, struct timespec *tp)
26 {
27 uint64_t time_ms = 0;
28
29 if (tp == NULL) {
30 errno = EINVAL;
31 return -1;
32 }
33
34 if (clock_id == CLOCK_MONOTONIC) {
35 time_ms = aos_now_ms();
36 tp->tv_sec = time_ms / 1000;
37 tp->tv_nsec = (time_ms % 1000) * 1000000;
38 } else if (clock_id == CLOCK_REALTIME) {
39 time_ms = aos_calendar_time_get();
40 tp->tv_sec = time_ms / 1000;
41 tp->tv_nsec = (time_ms % 1000) * 1000000;
42 } else {
43 errno = EINVAL;
44 return -1;
45 }
46
47 return 0;
48 }
49
clock_settime(clockid_t clock_id,const struct timespec * tp)50 int clock_settime(clockid_t clock_id, const struct timespec *tp)
51 {
52 uint64_t time_ms = 0;
53
54 /* only CLOCK_REALTIME can be set */
55 if ((clock_id != CLOCK_REALTIME) || (tp == NULL) ||
56 (tp->tv_nsec < 0) || (tp->tv_nsec >= 1000000000UL)) {
57 errno = EINVAL;
58 return -1;
59 }
60
61 time_ms = (tp->tv_sec * 1000) + (tp->tv_nsec / 1000000);
62 aos_calendar_time_set(time_ms);
63
64 return 0;
65 }
66
clock_nanosleep(clockid_t clock_id,int flags,const struct timespec * rqtp,struct timespec * rmtp)67 int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp,
68 struct timespec *rmtp)
69 {
70 int ret = 0;
71 int64_t time_ms = 0;
72 struct timespec tp = {0};
73
74 (void)rmtp;
75
76 if ((rqtp == NULL) || (rqtp->tv_sec < 0) || (rqtp->tv_nsec < 0)
77 || (rqtp->tv_nsec >= 1000000000UL)) {
78 return EINVAL;
79 }
80
81 if ((clock_id != CLOCK_MONOTONIC) && (clock_id != CLOCK_REALTIME)) {
82 return EINVAL;
83 }
84
85 if (flags == TIMER_ABSTIME) {
86 /* absolute time */
87 ret = clock_gettime(clock_id, &tp);
88 if (ret != 0) {
89 return ENOTSUP;
90 }
91
92 time_ms = (rqtp->tv_sec - tp.tv_sec) * 1000 + (rqtp->tv_nsec - tp.tv_nsec) / 1000000;
93 if (time_ms <= 0) {
94 /* The absolute time has passed, do not need to sleep. */
95 return 0;
96 }
97
98 } else {
99 /* relative time */
100 time_ms = rqtp->tv_sec * 1000 + rqtp->tv_nsec / 1000000;
101 }
102
103 aos_msleep(time_ms);
104
105 return 0;
106 }
107
108 /* Only support milliseconds resulation now by system tick. */
nanosleep(const struct timespec * rqtp,struct timespec * rmtp)109 int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
110 {
111 uint64_t time_ms = 0;
112
113 /* The rmtp parameter is not supported, because signal is not supported. */
114 (void)rmtp;
115
116 if ((rqtp == NULL) || (rqtp->tv_sec < 0) || (rqtp->tv_nsec < 0)
117 || (rqtp->tv_nsec >= 1000000000UL)) {
118 errno = EINVAL;
119 return -1;
120 }
121
122 time_ms = (rqtp->tv_sec * 1000) + (rqtp->tv_nsec / 1000000);
123 aos_msleep(time_ms);
124
125 return 0;
126 }
127
sleep(unsigned int seconds)128 unsigned int sleep(unsigned int seconds)
129 {
130 struct timespec tv = { .tv_sec = seconds, .tv_nsec = 0 };
131
132 if (nanosleep(&tv, &tv))
133 return tv.tv_sec;
134
135 return 0;
136 }
137
usleep(useconds_t us)138 int usleep(useconds_t us)
139 {
140 struct timespec tv = {
141 .tv_sec = us / 1000000,
142 .tv_nsec = (us % 1000000) * 1000
143 };
144
145 return nanosleep(&tv, &tv);
146 }
147