7b95428fa0
The original implementation of `usleep()` was not compliant to the POSIX spec in 3 ways. - calling thread may not be suspended (because `k_busy_wait()` was previously used for short durations) - if `usecs` > 1000000, previously we did not return -1 or set `errno` to `EINVAL` - if interrupted, previously we did not return -1 or set `errno` to `EINTR` This change addresses those issues to make `usleep()` more POSIX-compliant. Signed-off-by: Chris Friedt <cfriedt@meta.com>
50 lines
771 B
C
50 lines
771 B
C
/*
|
|
* Copyright (c) 2018 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <errno.h>
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/posix/unistd.h>
|
|
|
|
/**
|
|
* @brief Sleep for a specified number of seconds.
|
|
*
|
|
* See IEEE 1003.1
|
|
*/
|
|
unsigned sleep(unsigned int seconds)
|
|
{
|
|
int rem;
|
|
|
|
rem = k_sleep(K_SECONDS(seconds));
|
|
__ASSERT_NO_MSG(rem >= 0);
|
|
|
|
return rem / MSEC_PER_SEC;
|
|
}
|
|
/**
|
|
* @brief Suspend execution for microsecond intervals.
|
|
*
|
|
* See IEEE 1003.1
|
|
*/
|
|
int usleep(useconds_t useconds)
|
|
{
|
|
int32_t rem;
|
|
|
|
if (useconds >= USEC_PER_SEC) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
rem = k_usleep(useconds);
|
|
__ASSERT_NO_MSG(rem >= 0);
|
|
if (rem > 0) {
|
|
/* sleep was interrupted by a call to k_wakeup() */
|
|
errno = EINTR;
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|