Load memory data size in each time memory access boundary check in
multi-threading mode since it may be changed by other threads when
memory growing.
And use `memory->memory_data_size` instead of
`memory->num_bytes_per_page * memory->cur_page_count` to refine
the code.
When ref.func opcode refers to a function whose function index no smaller than
current function, the destination func should be forward-declared: it is declared
in the table element segments, or is declared in the export list.
In multi-threading, this line will eventually call `wasm_cluster_wait_for_all_except_self`:
`DEINIT_VEC(store->instances, wasm_instance_vec_delete)`
As the threads are joining they can call `wasm_interp_dump_call_stack` which tries to
use the module frames but they were already freed by this line:
`DEINIT_VEC(store->modules, wasm_module_vec_delete)`
This PR swaps the order that these are deleted so module is deleted after the instances.
Co-authored-by: Andrew Chambers <ncham@amazon.com>
Try using existing exec_env to execute wasm app's malloc/free func and
execute post instantiation functions. Create a new exec_env only when
no existing exec_env was found.
POLLRDNORM/POLLWRNORM may be not defined in uClibc, so replace them
with the equivalent POLLIN/POLLOUT.
Refer to https://www.man7.org/linux/man-pages/man2/poll.2.html
POLLRDNORM Equivalent to POLLIN
POLLWRNORM Equivalent to POLLOUT
Signed-off-by: Thomas Devoogdt <thomas.devoogdt@barco.com>
Update wasi-libc version to resolve the hang issue when running wasi-threads cases.
Implement custom sync primitives as a counterpart of `pthread_barrier_wait` to
attempt to replace pthread sync primitives since they seem to cause data races
when running with the thread sanitizer.
Use pre-created exec_env for instantiation and module_malloc/free,
use the same exec_env of the current thread to avoid potential
unexpected behavior.
And remove unnecessary shared_mem_lock in wasm_module_free,
which may cause dead lock.
Use the shared memory's shared_mem_lock to lock the whole atomic.wait and
atomic.notify processes, and use it for os_cond_reltimedwait and os_cond_notify,
so as to make the whole processes actual atomic operations:
the original implementation accesses the wait address with shared_mem_lock
and uses wait_node->wait_lock for os_cond_reltimedwait, which is not an atomic
operation.
And remove the unnecessary wait_map_lock and wait_lock, since the whole
processes are already locked by shared_mem_lock.
`wasi-sdk-20` pre-release can be used to avoid building `wasi-libc` to enable threads.
It's not possible to use `wasi-sdk-20` pre-release on Ubuntu 20.04 because of
incompatibility with the glibc version:
```bash
/opt/wasi-sdk/bin/clang: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found
(required by /opt/wasi-sdk/bin/clang)
```
- Remove notify_stale_threads_on_exception and change atomic.wait
to be interruptible by keep waiting and checking every one second,
like the implementation of poll_oneoff in libc-wasi
- Wait all other threads exit and then get wasi exit_code to avoid
getting invalid value
- Inherit suspend_flags of parent thread while creating new thread to
avoid terminated flag isn't set for new thread
- Fix wasi-threads test case update_shared_data_and_alloc_heap
- Add "Lib wasi-threads enabled" prompt for cmake
- Fix aot get exception, use aot_copy_exception instead
Fix a data race for test main_proc_exit_wait.c from #1963.
And fix atomic_wait logic that was wrong before:
- a thread 1 started executing wasm instruction wasm_atomic_wait
but hasn't reached waiting on condition variable
- a main thread calls proc_exit and notifies all the threads that reached
waiting on condition variable
Which leads to thread 1 hang on waiting on condition variable after that
Now it's atomically checked whether proc_exit was already called.
In the WASI thread test modified in this PR, malloc was used in multiple threads
without a lock. But wasi-libc implementation of malloc is not thread-safe.
Remove restrictions:
- Only 1 WASM app at a time
- Only 1 model at a time
- `graph` and `graph-execution-context` are ignored
Refer to previous document:
e8d718096d/core/iwasm/libraries/wasi-nn/README.md
- Implement atomic.fence to ensure a proper memory synchronization order
- Destroy exec_env_singleton first in wasm/aot deinstantiation
- Change terminate other threads to wait for other threads in
wasm_exec_env_destroy
- Fix detach thread in thread_manager_start_routine
- Fix duplicated lock cluster->lock in wasm_cluster_cancel_thread
- Add lib-pthread and lib-wasi-threads compilation to Windows CI
In wasm_cluster_create_thread, the new_exec_env is added into the cluster's
exec_env list before the thread is created, so other threads can access the
fields of new_exec_env once the cluster->lock is unlocked, while the
new_exec_env's handle is set later inside the thread routine. This may result
in the new_exec_env's handle be invalidly accessed by other threads.
- CMakeLists.txt: add lib_export.h to install list
- Fast JIT: enlarge spill cache size to enable several standalone cases
when hw bound check is disabled
- Thread manager: wasm_cluster_exit_thread may destroy an invalid
exec_env->module_inst when exec_env was destroyed before
- samples/socket-api: fix failure to run timeout_client.wasm
- enhance CI build wasi-libc and sample/wasm-c-api-imports CMakeLlist.txt
Support collecting code coverage with wamr-test-suites script by using
lcov and genhtml tools, eg.:
cd tests/wamr-test-suites
./test_wamr.sh -s spec -b -P -C
The default code coverage and html files are generated at:
tests/wamr-test-suites/workspace/wamr.lcov
tests/wamr-test-suites/workspace/wamr-lcov.zip
And update wamr-test-suites scripts to support testing GC spec cases to
avoid frequent synchronization conflicts between branch main and dev/gc.
Raising "wasi proc exit" exception, spreading it to other threads and then
clearing it in all threads may result in unexpected behavior: the sub thread
may end first, handle the "wasi proc exit" exception and clear exceptions
of other threads, including the main thread. And when main thread's
exception is cleared, it may continue to run and throw "unreachable"
exception. This also leads to some assertion failed.
Ignore exception spreading for "wasi proc exit" and don't clear exception
of other threads to resolve the issue.
And add suspend flag check after atomic wait since the atomic wait may
be notified by other thread when exception occurs.
Fix issues in the libc-wasi `poll_oneoff` when thread manager is enabled:
- The exception of a thread may be cleared when other thread runs into
`proc_exit` and then calls `clear_wasi_proc_exit_exception`, so should not
use `wasm_runtime_get_exception` to check whether an exception was
thrown, use `wasm_cluster_is_thread_terminated` instead
- We divided one time poll_oneoff into many times poll_oneoff to check
the exception to avoid long time waiting in previous PR, but if all events
returned by one time poll are all waiting events, we need to continue to
wait but not return directly.
Follow-up on #1951. Tested with multiple timeout values, with and without
interruption and measured the time spent sleeping.
- Use execute_post_instantiate_functions to call start, _initialize,
__post_instantiate, __wasm_call_ctors functions after instantiation
- Always call start function for both main instance and sub instance
- Only call _initialize and __post_instantiate for main instance
- Only call ___wasm_call_ctors for main instance and when bulk memory
is enabled and wasi import functions are not found
- When hw bound check is enabled, use the existing exec_env_tls
to call func for sub instance, and switch exec_env_tls's module inst
to current module inst to avoid checking failure and using the wrong
module inst
Add shared memory lock when accessing the address to atomic wait/notify
inside linear memory to resolve its data race issue.
And statically initialize the goto table of interpreter labels to resolve the
data race issue of accessing the table.
The problem was found by a `Golang + WAMR (as CGO)` wrapped by EGO
in SGX Enclave.
`fstat()` in EGO returns dummy values:
- EGO uses a `mount` configuration to define the mount points that apply
the host file system presented to the Encalve.
- EGO has a different programming model: the entire application runs inside
the enclave. Manual ECALLs/OCALLs by application code are neither
required nor possible.
Add platform ego and add macro control for the return value checking of
`fd_determine_type_rights` in libc-wasi to resolve the issue.
The function has been there for long. While what it does look a bit unsafe
as it calls a function which may be not wasm-wise exported explicitly, it's
useful and widely used when implementing callback-taking APIs, including
our pthread_create's implementation.
Destroy child thread's exec_env before destroying its module instance and
add the process into cluster's lock to avoid possible data race: if exec_env
is removed from custer's exec_env_list and destroyed later, the main thread
may not wait it and start to destroy the wasm runtime, and the destroying
of the sub thread's exec_env may free or overread/written an destroyed or
re-initialized resource.
And fix an issue in wasm_cluster_cancel_thread.
The start/initialize functions of wasi module are to do some initialization work
during instantiation, which should be only called one time in the instantiation
of main instance. For example, they may initialize the data in linear memory,
if the data is changed later by the main instance, and re-initialized again by
the child instance, unexpected behaviors may occur.
And clear a shadow warning in classic interpreter.