Skip to content

Commit d9b5d66

Browse files
committed
fix(zephyr): Refactor the nanosleep and helpers functions
1 parent 5c531b6 commit d9b5d66

File tree

1 file changed

+52
-46
lines changed

1 file changed

+52
-46
lines changed

core/shared/platform/zephyr/zephyr_sleep.c

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -30,85 +30,91 @@
3030
* Note: this assumes `CONFIG_POSIX_API=n` in the Zephyr application.
3131
*/
3232

33-
#ifdef CONFIG_TIMEOUT_64BIT
34-
static int64_t timespec_to_ticks(const os_timespec *ts);
35-
#else
36-
static uint32_t timespec_to_ticks(const os_timespec *ts);
37-
#endif
33+
static k_ticks_t timespec_to_ticks(const os_timespec *ts);
34+
static void ticks_to_timespec(k_ticks_t ticks, os_timespec *ts);
3835

3936
__wasi_errno_t
4037
os_nanosleep(const os_timespec *req, os_timespec *rem)
4138
{
4239
k_timeout_t timeout;
40+
k_ticks_t rem_ticks;
4341

4442
if (req == NULL){
4543
return __WASI_EINVAL;
4644
}
4745

48-
timeout.ticks = (k_ticks_t) timespec_to_ticks(req);
46+
if (req->tv_sec < 0 || req->tv_nsec < 0 || req->tv_nsec >= 1000000000) {
47+
return __WASI_EINVAL;
48+
}
49+
50+
if (req->tv_sec == 0 && req->tv_nsec == 0) {
51+
if (rem != NULL) {
52+
rem->tv_sec = 0;
53+
rem->tv_nsec = 0;
54+
}
55+
return __WASI_ESUCCESS;
56+
}
57+
58+
timeout.ticks = timespec_to_ticks(req);
4959

5060
/*
5161
* The function `int32_t k_sleep(k_timeout_t timeout)` return either:
5262
* * 0 requested time elaspsed.
5363
* * >0 remaining time in ms (due to k_wakeup).
5464
*/
5565
int32_t rc = k_sleep(timeout);
56-
if (rem != NULL && 0 < rc){
57-
rem->tv_sec = rc / 1000;
58-
rem->tv_nsec = ( rc % 1000 ) * 1000000;
66+
if (rem != NULL) {
67+
if (rc > 0) {
68+
69+
#ifdef CONFIG_TIMEOUT_64BIT
70+
rem_ticks = (k_ticks_t)((uint64_t)rc * CONFIG_SYS_CLOCK_TICKS_PER_SEC / 1000);
71+
#else /* CONFIG_TIMEOUT_32BIT */
72+
uint64_t temp_ticks = (uint64_t)rc * CONFIG_SYS_CLOCK_TICKS_PER_SEC / 1000;
73+
rem_ticks = (k_ticks_t)(temp_ticks > UINT32_MAX ? UINT32_MAX : temp_ticks);
74+
#endif
75+
ticks_to_timespec(rem_ticks, rem);
76+
} else {
77+
rem->tv_sec = 0;
78+
rem->tv_nsec = 0;
79+
}
5980
}
6081

6182
return __WASI_ESUCCESS;
6283
}
6384

6485

65-
#ifdef CONFIG_TIMEOUT_64BIT
66-
67-
static int64_t timespec_to_ticks(const os_timespec *ts)
86+
static k_ticks_t timespec_to_ticks(const os_timespec *ts)
6887
{
6988
const uint64_t ticks_per_sec = CONFIG_SYS_CLOCK_TICKS_PER_SEC;
70-
uint64_t ticks = 0;
89+
uint64_t total_ns, ticks;
7190

72-
if (ts->tv_sec > UINT64_MAX / ticks_per_sec) {
73-
return UINT64_MAX;
74-
}
91+
total_ns = (uint64_t)ts->tv_sec * 1000000000ULL + (uint64_t)ts->tv_nsec;
92+
ticks = total_ns * ticks_per_sec / 1000000000ULL;
7593

76-
ticks = (uint64_t)ts->tv_sec * ticks_per_sec;
77-
78-
if (ts->tv_nsec > 0) {
79-
uint64_t add = (uint64_t)ts->tv_nsec * ticks_per_sec / 1000000000ULL;
80-
if (ticks > UINT64_MAX - add) {
81-
return UINT64_MAX;
82-
}
83-
ticks += add;
94+
#ifdef CONFIG_TIMEOUT_64BIT
95+
if (ticks > INT64_MAX) {
96+
return INT64_MAX;
8497
}
98+
#else /* CONFIG_TIMEOUT_32BIT */
99+
if (ticks > UINT32_MAX) {
100+
return UINT32_MAX;
101+
}
102+
#endif
85103

86-
return ticks;
104+
return (k_ticks_t)ticks;
87105
}
88106

89-
#else /* CONFIG_TIMEOUT_32BIT */
90-
91-
static uint32_t timespec_to_ticks(const os_timespec *ts)
107+
static void ticks_to_timespec(k_ticks_t ticks, os_timespec *ts)
92108
{
93-
const uint32_t ticks_per_sec = CONFIG_SYS_CLOCK_TICKS_PER_SEC;
94-
uint32_t ticks = 0;
95-
96-
if (ts->tv_sec > UINT32_MAX / ticks_per_sec) {
97-
return UINT32_MAX;
98-
}
99-
100-
ticks = (uint32_t)ts->tv_sec * ticks_per_sec;
109+
const uint64_t ticks_per_sec = CONFIG_SYS_CLOCK_TICKS_PER_SEC;
110+
uint64_t total_ns;
101111

102-
if (ts->tv_nsec > 0) {
103-
uint64_t add64 = (uint64_t)ts->tv_nsec * ticks_per_sec;
104-
uint32_t add = (uint32_t)(add64 / 1000000000ULL);
105-
if (ticks > UINT32_MAX - add) {
106-
return UINT32_MAX;
107-
}
108-
ticks += add;
112+
if (ts == NULL) {
113+
return;
109114
}
110115

111-
return ticks;
112-
}
116+
total_ns = ((uint64_t)ticks * 1000000000ULL) / ticks_per_sec;
113117

114-
#endif /* CONFIG_TIMEOUT_64BIT */
118+
ts->tv_sec = (long)(total_ns / 1000000000ULL);
119+
ts->tv_nsec = (long)(total_ns % 1000000000ULL);
120+
}

0 commit comments

Comments
 (0)