wasix-org / wasix-libc

wasix libc implementation for WebAssembly
https://wasi.dev
Other
114 stars 19 forks source link

nanosleep doesn't work as expected #26

Closed daichifukui closed 6 months ago

daichifukui commented 1 year ago

Description

nanosleep does not respect the sleep duration and the routine returns immediately if the duration is shorter than 1 second.

Conditions

Steps to reproduce

  1. view source code
    
    $ cat nanosleep_main.c
    #include <time.h>
    #include <stdio.h>

int main(void) { int ret; struct timespec ts; ts.tv_nsec=999999999; ret = nanosleep(&ts, NULL); if (ret) perror("clock_nanosleep"); return 0; }


2. compile

$ /home/user/wasi-sdk-20.0/bin/clang \ --sysroot=/home/user/wasix-libc/sysroot \ -Wall \ -Wno-nonnull \ -Wextra \ -O2 \ -Wl,--max-memory=4294967296 \ -Wl,--export-dynamic \ nanosleep_main.c \ -o n_main


3. run

$ /home/user/.wasmer/bin/wasmer run --enable-all --verbose ./n_main 2023-09-22T05:15:10.482290Z INFO ThreadId(01) execute_wasm: wasmer_cli::commands::run: enter 2023-09-22T05:15:10.482572Z INFO ThreadId(01) execute_wasm:execute_wasi_module: wasmer_cli::commands::run: enter 2023-09-22T05:15:10.483636Z INFO ThreadId(01) execute_wasm:execute_wasi_module: wasmer_cli::commands::run: close time.busy=1.06ms time.idle=1.52µs 2023-09-22T05:15:10.483794Z INFO ThreadId(01) execute_wasm: wasmer_cli::commands::run: close time.busy=1.51ms time.idle=2.76µs


With regard to the result above, `nanosleep` should sleep for 999999999ns (almost 1 second) but it sleeps for around 1.5ms, which is much shorter than expected

**Expected behaviour**  

nanosleep sleeps for requested duration even if the duration is shorter than 1 second

**Actual behaviour**  

nanosleep sleeps for only a few milliseconds and returns immediately if the duration is shorter than 1 second

**Additional info**

nanosleep works as expected if the duration is equal to or longer than 1 second.

view source code

$ cat nanosleep_main_1s.c

include

include

int main(void) { int ret; struct timespec ts; ts.tv_sec=1; ret = nanosleep(&ts, NULL); if (ret) perror("clock_nanosleep"); return 0; }

compile

$ /home/user/wasi-sdk-20.0/bin/clang \ --sysroot=/home/user/wasix-libc/sysroot \ -Wall \ -Wno-nonnull \ -Wextra \ -O2 \ -Wl,--max-memory=4294967296 \ -Wl,--export-dynamic \ nanosleep_main_1s.c \ -o n_main_1s

run

$ /home/user/.wasmer/bin/wasmer run --enable-all --verbose ./n_main_1s 2023-09-22T04:43:46.802396Z INFO ThreadId(01) execute_wasm: wasmer_cli::commands::run: enter 2023-09-22T04:43:46.802479Z INFO ThreadId(01) execute_wasm:execute_wasi_module: wasmer_cli::commands::run: enter 2023-09-22T04:43:47.811808Z INFO ThreadId(01) execute_wasm:execute_wasi_module: wasmer_cli::commands::run: close time.busy=1.01s time.idle=2.82µs 2023-09-22T04:43:47.811890Z INFO ThreadId(01) execute_wasm: wasmer_cli::commands::run: close time.busy=1.01s time.idle=3.73µs


In addition, if we use wasi-libc instead of wasix-libc, nanosleep works as expected with the sleep duration shorter than 1 second

$ cat nanosleep_main.c

include

include

int main(void) { int ret; struct timespec ts; ts.tv_nsec=999999999; ret = nanosleep(&ts, NULL); if (ret) perror("clock_nanosleep"); return 0; }

$ /home/user/wasi-sdk-20.0/bin/clang \ --sysroot=/home/user/wasi-libc/sysroot/ \ -Wall \ -Wno-nonnull \ -Wextra \ -O2 \ -Wl,--max-memory=4294967296 \ -Wl,--export-dynamic \ nanosleep_main.c \ -o n_main

$ /home/user/.wasmer/bin/wasmer run --enable-all --verbose ./n_main 2023-09-22T06:07:26.452257Z INFO ThreadId(01) execute_wasm: wasmer_cli::commands::run: enter 2023-09-22T06:07:26.452517Z INFO ThreadId(01) execute_wasm:execute_wasi_module: wasmer_cli::commands::run: enter 2023-09-22T06:07:27.454365Z INFO ThreadId(01) execute_wasm:execute_wasi_module: wasmer_cli::commands::run: close time.busy=1.00s time.idle=2.81µs 2023-09-22T06:07:27.454435Z INFO ThreadId(01) execute_wasm: wasmer_cli::commands::run: close time.busy=1.00s time.idle=3.11µs