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
4037os_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