Skip to content

Commit 3cdf718

Browse files
cfriedtcarlescufi
authored andcommitted
lib: posix: nanosleep: round up to the nearest microsecond
We must round up to the nearest microsecond in order to fulfill the nanosleep(2) API requirement of sleeping for *at least* that many nanoseconds. The only platform with an upper-bound check right now is Nordic. Fixes #28483 Signed-off-by: Christopher Friedt <[email protected]>
1 parent d04ff1a commit 3cdf718

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

lib/posix/nanosleep.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <errno.h>
1111
/* required for struct timespec */
1212
#include <posix/time.h>
13+
#include <sys/util.h>
1314
#include <sys_clock.h>
1415

1516
/**
@@ -20,6 +21,7 @@
2021
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
2122
{
2223
uint64_t ns;
24+
uint64_t us;
2325
const bool update_rmtp = rmtp != NULL;
2426

2527
if (rqtp == NULL) {
@@ -41,14 +43,17 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
4143
/* If a user passes this in, we could be here a while, but
4244
* at least it's technically correct-ish
4345
*/
44-
ns = rqtp->tv_nsec + NSEC_PER_SEC;
45-
k_sleep(K_SECONDS(rqtp->tv_sec - 1));
46+
ns = rqtp->tv_nsec + NSEC_PER_SEC
47+
+ k_sleep(K_SECONDS(rqtp->tv_sec - 1)) * NSEC_PER_MSEC;
4648
} else {
4749
ns = rqtp->tv_sec * NSEC_PER_SEC + rqtp->tv_nsec;
4850
}
4951

50-
/* currently we have no mechanism to achieve greater resolution */
51-
k_busy_wait(ns / NSEC_PER_USEC);
52+
/* TODO: improve upper bound when hr timers are available */
53+
us = ceiling_fraction(ns, NSEC_PER_USEC);
54+
do {
55+
us = k_usleep(us);
56+
} while (us != 0);
5257

5358
do_rmtp_update:
5459
if (update_rmtp) {

0 commit comments

Comments
 (0)