Add simple infrastructure to add more unit tests in the future. At the moment tests
are only executed on Linux, but can be extended to other platforms if needed.
Use https://github.com/google/googletest/ as a framework.
As a part of stress-testing we want to ensure that mutex implementation is working
correctly and protecting shared resource to be allocated from other threads when
mutex is locked.
This test covers the most common situations that happen when some program uses
mutexes like locks from various threads, locks from the same thread etc.
We need to apply some bug fixes that were merged to wasi-libc because wasi-sdk-20
is about half a year old.
It is a temporary solution and the code will be removed when wasi-sdk 21 is released.
- Inherit shared memory from the parent instance, instead of
trying to look it up by the underlying module. The old method
works correctly only when every cluster uses different module.
- Use reference count in WASMMemoryInstance/AOTMemoryInstance
to mark whether the memory is shared or not
- Retire WASMSharedMemNode
- For atomic opcode implementations in the interpreters, use
a global lock for now
- Update the internal API users
(wasi-threads, lib-pthread, wasm_runtime_spawn_thread)
Fixes https://github.com/bytecodealliance/wasm-micro-runtime/issues/1962
- Avoid destroying module instance repeatedly in pthread_exit_wrapper and
wasm_thread_cluster_exit.
- Wait enough time in pthread_join_wrapper for target thread to exit and
destroy its resources.
We need to make a test that runs longer than the tests we had before to check
some problems that might happen after running for some time (e.g. memory
corruption or something else).
Tests were failing because the right permissions were not provided to iwasm.
Also, test failures didn't trigger build failure due to typo - also fixed in this change.
In addition to that, this PR fixes a few issues with the test itself:
* the `server_init_complete` was not reset early enough causing the client to occasionally
assume the server started even though it didn't yet
* set `SO_REUSEADDR` on the server socket so the port can be reused shortly after
closing the previous socket
* defined receive-send-receive sequence from server to make sure server is alive at the
time of sending message
And return ENOSYS. We do that so we can at least compile the code on CI.
We'll be gradually enabling more and more functions.
Also, enabled `proc_raise()` for windows.
* disable translations of errno codes that aren't defined on Windows
* undef `min()` macro if it is defined to not conflict with the `min()` function we define
* implement `shed_yield` wasi call
* disable some of the features in the config for windows by default
We have observed a significant performance degradation after merging
https://github.com/bytecodealliance/wasm-micro-runtime/pull/1991
Instead of protecting suspend flags with a mutex, we implement the flags
as atomic variable and only use mutex when atomics are not available
on a given platform.
Build wasi-libc library on Windows since libuv may be not supported. This PR is a first step
to make it working, but there's still a number of changes to get it fully working.
Calling `__wasi_sock_addr_resolve` syscall causes native stack overflow.
Given this is a standard function available in WAMR, we should have at least
the default stack size large enough to handle this case.
The socket tests were updated so they also run in separate thread, but
the simple retro program is:
```C
void *th(void *p)
{
struct addrinfo *res;
getaddrinfo("amazon.com", NULL, NULL, &res);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t pt;
pthread_create(&pt, NULL, th, NULL);
pthread_join(pt, NULL);
return 0;
}
```
## Context
Currently, WAMR supports compiling iwasm with flag `WAMR_BUILD_WASI_NN`.
However, there are scenarios where the user might prefer having it as a shared library.
## Proposed Changes
Decouple wasi-nn context management by internally managing the context given
a module instance reference.
## Context
Path to models use `/assets` for testing inside docker. While testing directly from
the repo we are forced to use soft-links or modify the paths.
## Proposed Changes
Use relative path and adjust docker volumes in docs.
Major changes:
- Public headers inside `wasi-nn/include`
- Put cmake files in `cmake` folder
- Make linux iwasm link with `${WASI_NN_LIBS}` so iwasm can enable wasi-nn
This PR attempts to search for the system libuv and use it if found instead of
downloading it. As reported in #1831, this is needed because some tools
build in a sandbox and clear the extra sources.
For some platforms WAMR gets compiled with `CONFIG_HAS_CLOCK_NANOSLEEP=1`,
while `clock_nanosleep` is not present at the platform, which causes compilation error.
Add check for macro `DISABLE_CLOCK_NANOSLEEP` to resolve the issue, only when
the macro isn't defined can the macro `CONFIG_HAS_CLOCK_NANOSLEEP` take effect.
Add VX delegation as an external delegation of TFLite, so that several NPU/GPU
(from VeriSilicon, NXP, Amlogic) can be controlled via WASI-NN.
Test Code can work with the X86 simulator.
Fix issue reported in #2172: wasm-c-api `wasm_func_call` may use a wrong exec_env
when multi-threading is enabled, with error "invalid exec env" reported
Fix issue reported in #2149: main instance's `c_api_func_imports` are not passed to
the counterpart of new thread's instance in wasi-threads mode
Fix issue of invalid size calculated to copy `c_api_func_imports` in pthread mode
And refactor the code to use `wasm_cluster_dup_c_api_imports` to copy the
`c_api_func_imports` to new thread for wasi-threads mode and pthread mode.
Currently, if a thread is spawned and raises an exception after the main thread
has finished, iwasm returns with success instead of returning 1 (i.e. error).
Since wasm_runtime_get_wasi_exit_code waits for all threads to finish and only
returns the wasi exit code, this PR performs the exception check again and
returns error if an exception was raised.
Since the Tensorflow library is already installed in many cases(especially in the
case of the embedded system), move the installation code to find_package.
According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of
at least 16 bit (see sections 7.17 and 7.18.3), it may be uint32 in 32-bit platforms:
https://en.cppreference.com/w/cpp/types/size_t
Calling function `size_t min(size_t, size_t)` with two uint64 arguments may get
invalid result.
Co-authored-by: Georgii Rylov <godjan@amazon.co.uk>
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.
`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.
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.
Add APIs to help prepare the imports for the wasm-c-api `wasm_instance_new`:
- wasm_importtype_is_linked
- wasm_runtime_is_import_func_linked
- wasm_runtime_is_import_global_linked
- wasm_extern_new_empty
For wasm-c-api, developer may use `wasm_module_imports` to get the import
types info, check whether an import func/global is linked with the above API,
and ignore the linking of an import func/global with `wasm_extern_new_empty`.
Sample `wasm-c-api-import` is added and document is updated.
- Split logic in several dockers
- runtime: wasi-nn-cpu and wasi-nn- Nvidia-gpu.
- compilation: wasi-nn-compile. Prepare the testing wasm and generates the TFLites.
- Implement GPU support for TFLite with Opencl.
- Reorganize the library structure
- Use the latest version of `wasi-nn` wit (Oct 25, 2022):
0f77c48ec1/wasi-nn.wit.md
- Split logic that converts WASM structs to native structs in a separate file
- Simplify addition of new frameworks
This syscall doesn't need allocating stack or TLS and it's expected from the application
to do that instead. E.g. WASI-libc already does this for `pthread_create`.
Also fix some of the examples to allocate memory for stack and not use stack before
the stack pointer is set to a correct value.
Because stack grows from high address towards low address, the value
returned by malloc is the end of the stack, not top of the stack. The top
of the stack is the end of the allocated space (i.e. address returned by
malloc + cluster size).
Refer to #1790.
According to the [WASI thread specification](https://github.com/WebAssembly/wasi-threads/pull/16),
some thread identifiers are reserved and should not be used. In fact, only IDs between `1` and
`0x1FFFFFFF` are valid.
The thread ID allocator has been moved to a separate class to avoid polluting the
`lib_wasi_threads_wrapper` logic.
Allow to add watchpoints to variables for source debugging. For instance:
`breakpoint set variable var`
will pause WAMR execution when the address at var is written to.
Can also set read/write watchpoints by passing r/w flags. This will pause
execution when the address at var is read:
`watchpoint set variable -w read var`
Add two linked lists for read/write watchpoints. When the debug message
handler receives a watchpoint request, it adds/removes to one/both of these
lists. In the interpreter, when an address is read or stored to, check whether
the address is in these lists. If so, throw a sigtrap and suspend the process.
This PR allows reusing thread ids once they are released. That is done by using
a stack data structure to keep track of the used ids.
When a thread is created, it takes an available identifier from the stack. When
the thread exits, it returns the id to the stack of available identifiers.
For now this implementation uses thread manager.
Not sure whether thread manager is needed in that case. In the future there'll be likely another syscall added (for pthread_exit) and for that we might need some kind of thread management - with that in mind, we keep thread manager for now and will refactor this later if needed.
Allow to add watchpoints to variables for source debugging. For instance:
`breakpoint set variable var`
will pause WAMR execution when the address at var is written to.
Can also set read/write watchpoints by passing r/w flags. This will pause
execution when the address at var is read:
`watchpoint set variable -w read var`
Add two linked lists for read/write watchpoints. When the debug message
handler receives a watchpoint request, it adds/removes to one/both of these
lists. In the interpreter, when an address is read or stored to, check whether
the address is in these lists. If so, throw a sigtrap and suspend the process.
Change main thread hangs when encounter debugger encounters error to
main thread exits when debugger encounters error
Change main thread blocks when debugger detaches to
main thread continues executing when debugger detaches, and main thread
exits normally when finishing executing
Current SGX lib-rats wasm module hash is stored in a global buffer,
which may be overwritten if there are multiple wasm module loadings.
We move the module hash into the enclave module to resolve the issue.
And rename the SGX_IPFS macro/variable in Makefile and Enclave.edl to
make the code more consistent.
And refine the sgx-ra sample document.