diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index d20537ad0..bc9c3c9b4 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -2135,7 +2135,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds, // nanosleep(). This is incorrect, but good enough for now. os_timespec ts; convert_timestamp(in[0].u.u.clock.timeout, &ts); - // nanosleep(&ts, NULL); + os_nanosleep(&ts, NULL); } break; case __WASI_CLOCK_REALTIME: @@ -2163,7 +2163,7 @@ wasmtime_ssp_poll_oneoff(wasm_exec_env_t exec_env, struct fd_table *curfds, // Relative sleeps can be done using nanosleep(). os_timespec ts; convert_timestamp(in[0].u.u.clock.timeout, &ts); - // nanosleep(&ts, NULL); + os_nanosleep(&ts, NULL); } break; default: diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index 41ec5742b..ffd028c1e 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -1669,28 +1669,112 @@ __wasi_errno_t os_clock_time_get(__wasi_clockid_t clock_id, __wasi_timestamp_t precision, __wasi_timestamp_t *time); -#ifdef __cplusplus -} -#endif -/* Experimental */ +/**************************************************** + * Section 5 * + * Experimental functions * + ****************************************************/ -/* Used in posix.c around L2259 and expect the return code - * of ioctl() directly. +/** + * NOTES: + * The bellow functions were defined after increasing the support for the + * Zephyr platform to get the full WASI libc running. + * + * If you don't need to support WASI libc, there is no need to implement these + * APIs. + * + * We could also move these definitions to the proper sections + * (File, Time, ...) but still keep them here until we get more feedback or + * observe edges cases. + */ + +/** + * @brief Control device. + * + * The `ioctl` function was one of the POSIX function used without platform + * abastraction API in the `sandboxed-system-primitives` and particularly in the + * `wasmtime_ssp_poll_oneoff` function. + * + * @param handle A platform file handler. + * @param request A platform-dependent request code. + * @param argp Usually an untyped pointer to memory. + * + * @return + * __WASI_ESUCCESS On success + * __WASI_EBADF handle is not a valid file handler. + * __WASI_EFAULT argp references an inaccessible memory area. + * __WASI_EINVAL request or argp is not valid. + * __WASI_ENOTTY handle is not associated with a character special device. + * __WASI_ENOTTY The specified request does not apply to the kind of + * object that the file handler handle references. + * + * NOTE: We seem to only use/support the `FIONREAD` request code: + * + * FIONREAD Get the number of bytes in the input buffer. */ int os_ioctl(os_file_handle handle, int request, ...); -/* Higher level API: - * __wasi_errno_t - * blocking_op_poll(wasm_exec_env_t exec_env, os_poll_file_handle *pfds, - * os_nfds_t nfds, int timeout_ms, int *retp) - * Already format the errno and expect the return code of poll() directly. +/** + * @brief Wait for some event on a file descriptor. + * + * For more context, the higher level API `blocking_op_poll`. + * + * __wasi_errno_t + * blocking_op_poll(wasm_exec_env_t exec_env, os_poll_file_handle *pfds, + * os_nfds_t nfds, int timeout_ms, int *retp) + * + * Format the error code (errno) and expect the return code of (POSIX) `poll()` + * directly hence the `int` return type. + * + * @param pfds A poll file descriptors array + * @param nfs The size of the poll file descriptors array + * @param timeout Specify the number of ms that poll is busy waiting. + * */ int os_poll(os_poll_file_handle *pfds, os_nfds_t nfs, int timeout); +/** + * @brief Compare two platform's file handle/descriptor. + * + * This function should ALWAYS be used when comparaing file handlers because + * for some platforms (Windows, Zephyr, etc...) the `os_file_handle` type is + * a structure and not a primary type like for POSIX. + * + * @param handle1 First file handle or constant. + * @param handle2 Second file handle. + * + * @return + * true The file handlers are similar. + * false The file handlers don't match. + */ bool os_compare_file_handle(os_file_handle handle1, os_file_handle handle2); + +/** + * @brief high-resolution sleep + * + * The `nanosleep` function was the last POSIX function used without platform + * abastraction API in the `sandboxed-system-primitives` and particularly in the + * `wasmtime_ssp_poll_oneoff` function. + * + * @param req time requiered to sleep. + * @param rem remaining time in the case that the function is interrupted. + * + * @return + * __WASI_ESUCCESS On success + * __WASI_EFAULT Problem with copying information. + * __WASI_EINTR The sleep has been interrupted. + * __WASI_EINVAL The req input is badly formed. + */ +__wasi_errno_t +os_nanosleep(os_timespec *req, os_timespec *rem); + + +#ifdef __cplusplus +} +#endif + #endif /* #ifndef PLATFORM_API_EXTENSION_H */ diff --git a/core/shared/platform/zephyr/shared_platform.cmake b/core/shared/platform/zephyr/shared_platform.cmake index f424b9720..f0b4a5ecc 100644 --- a/core/shared/platform/zephyr/shared_platform.cmake +++ b/core/shared/platform/zephyr/shared_platform.cmake @@ -19,6 +19,7 @@ if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1) list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/zephyr_socket.c) list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/zephyr_file.c) list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/zephyr_clock.c) + list(REMOVE_ITEM source_all ${PLATFORM_SHARED_DIR}/zephyr_sleep.c) else() include (${CMAKE_CURRENT_LIST_DIR}/../common/libc-util/platform_common_libc_util.cmake) set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE}) diff --git a/core/shared/platform/zephyr/zephyr_sleep.c b/core/shared/platform/zephyr/zephyr_sleep.c new file mode 100644 index 000000000..e6236ace4 --- /dev/null +++ b/core/shared/platform/zephyr/zephyr_sleep.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2024 Grenoble INP - ESISAR. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "platform_api_extension.h" + +// #include + +/* + * Assuming CONFIG_POSIX_API=n + * Inspired zephyr/lib/posix/options/clock.c + */ + +__wasi_errno_t +os_nanosleep(os_timespec *req, os_timespec *rem) +{ + // __wasi_errno_t ret; + + // if (req == NULL){ + // return __WASI_EINVAL; + // } + + // /* + // * os_timespec is typedef'ed to struct timespec so it's one to one. + // * Also sys_clock_nanosleep return either: + // * * 0 on sucess + // * * -EINVAL on failure + // */ + // int rc = sys_clock_nanosleep(SYS_CLOCK_REALTIME, 0, req, rem); + // if (0 > rc){ + // return __WASI_EINVAL; + // } + + return __WASI_ESUCCESS; +} + +/* + * Don't exist in v3.7 + * + * Inspired zephyr/lib/posix/options/clock.c on main + */ + +// int sys_clock_nanosleep(int clock_id, int flags, const struct timespec *rqtp, +// struct timespec *rmtp) +// { +// k_timepoint_t end; +// k_timeout_t timeout; +// struct timespec duration; +// const bool update_rmtp = rmtp != NULL; +// const bool abstime = (flags & SYS_TIMER_ABSTIME) != 0; + + +// /* +// * Arguments checks +// */ +// if((clock_id != SYS_CLOCK_MONOTONIC) && +// (clock_id != SYS_CLOCK_REALTIME)){ +// return __WASI_EINVAL; +// } + +// if((rqtp->tv_sec < 0) || +// (rqtp->tv_nsec < 0) || +// (rqtp->tv_nsec >= (long)NSEC_PER_SEC)){ +// return __WASI_EINVAL; +// } + + +// if (abstime) { +// /* convert absolute time to relative time duration */ +// (void)sys_clock_gettime(clock_id, &duration); +// (void)timespec_negate(&duration); +// (void)timespec_add(&duration, rqtp); +// } else { +// duration = *rqtp; +// } + +// /* sleep for relative time duration */ +// if ((sizeof(rqtp->tv_sec) == sizeof(int64_t)) && +// unlikely(rqtp->tv_sec >= (time_t)(UINT64_MAX / NSEC_PER_SEC))) { +// uint64_t ns = (uint64_t)k_sleep(K_SECONDS(duration.tv_sec - 1)) * NSEC_PER_MSEC; +// struct timespec rem = { +// .tv_sec = (time_t)(ns / NSEC_PER_SEC), +// .tv_nsec = ns % NSEC_PER_MSEC, +// }; + +// duration.tv_sec = 1; +// (void)timespec_add(&duration, &rem); +// } + +// timeout = timespec_to_timeout(&duration, NULL); +// end = sys_timepoint_calc(timeout); +// do { +// (void)k_sleep(timeout); +// timeout = sys_timepoint_timeout(end); +// } while (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)); + +// if (update_rmtp) { +// *rmtp = (struct timespec){ +// .tv_sec = 0, +// .tv_nsec = 0, +// }; +// } + +// return 0; +// }