* Implement the critical part of wasi_thread_start in asm
It's fragile to set up the critical part of C environment in C.
* Specify --target for asm files as well
* wasi_thread_start: Move __tls_base initialization to asm as well
The current wasi-threads has no thread-exit functionality.
Thus it isn't straightforward to implement pthread_exit
without leaking thread context. This commit simply disables
pthread_exit for now.
Also, instead of abusing `wasi_proc_exit` for thread exit,
make `wasi_thread_start` return.
Note: `wasi_proc_exit` is supposed to terminate all threads
in the "process", not only the calling thread.
Note: Depending on the conclusion of the discussion about
`wasi_thread_exit`, we might revisit this change later.
References:
https://github.com/WebAssembly/wasi-threads/issues/7https://github.com/WebAssembly/wasi-threads/pull/17
When compiling with `-z stack-size` flag, only the main thread's stack
size is set to the specified value and other threads use musl's default value.
That's inconsistent with LLD's `-Wl,-stack_size`.
I think we can make it similar to MUSL's behavior, where thread's stack
size can be set via `PT_GNU_STACK` program header (via `-Wl,-z,stack-size`
flag).
Configuring stack size through `pthread_attr_t` still work as expected and
overrides the defaults ([pthread_create.c](be1ffd6a9e/libc-top-half/musl/src/thread/pthread_create.c (L362)))
default settings.
In building some `libc-test` tests, I found these functions were not
compiled in. This change adds `pthread_barrier_init`,
`pthread_barrier_wait`, and `pthread_barrier_destroy` to the
`THREAD_MODEL=posix` build. As has been done with previous pthreads PRs,
this PR skips any inter-process locking by removing any calls to
`__vm_lock` and friends. If in the future WASI gains the "process"
concept, then these locations (and the pre-existing ones) will need to
be modified.
The pthreads API exposes functions for querying the attributes of a
thread. This change allows these functions to be compiled in the
`THREAD_MODEL=posix` build. Some functions are skipped (and documented);
they can be added if/when needed. This change is motivated by a
`libc-test` test that uses these functions.
1e4e2433bc
enabled sign-ext and mutable-globals by default, which adds
corresponding __wasm_-prefixed #defines.
9e956995db
changed the definition of __GNUC_VA_LIST to match that of GCC headers,
leaving it without a value.
This function returns the address of `errno`, which makes it easier to
access from non-C languages since `errno` is a thread-local variable
which requires a special ABI.
* threads: implement init of TLS and stack pointer
* fix: rename wasi_snapshot_preview2_thread_spawn to wasi_thread_spawn
Signed-off-by: Harald Hoyer <harald@profian.com>
* fix: change signature of wasi_thread_start
Signed-off-by: Harald Hoyer <harald@profian.com>
* fix: pthread_exit for WASI
Can't use `exit()` because it is too high level.
Have to unlock the thread list.
Signed-off-by: Harald Hoyer <harald@profian.com>
* fix: initialize struct pthread for the main thread
Signed-off-by: Harald Hoyer <harald@profian.com>
* fix: store the aligned stack minus `struct start_args`
Signed-off-by: Harald Hoyer <harald@profian.com>
Signed-off-by: Harald Hoyer <harald@profian.com>
Co-authored-by: Harald Hoyer <harald@profian.com>
* threads: implement `pthread_create`
As described in the [`wasi-threads`] proposal, this change implements
`pthread_create` using the new `wasi_thread_spawn(void *arg)` API. As
described there, `wasi-libc` exports the thread entry point with the
expected name, `wasi_thread_start`, and then unwraps the passed argument
`struct` to invoke the user function with the user argument `struct`.
[`wasi-threads`]: https://github.com/WebAssembly/wasi-threads/pull/5
Previously, the TID was only passed to the child thread entry point; the
parent thread was forced to wait until the child thread set the TID in
the pthread structure. With this change, the TID will be passed not only
to the child thread but also returned to the parent thread, so that
either side can make progress. The `i32.store` becomes an
`i32.atomic.store` to avoid concurrent writes.
I'm not sure if the function really has to be exported. If so, we should
probably move it to a separate compilation unit, otherwise it will be defined
multiple times (e.g. in `strerror.o` and `__lctrans.o`) causing linker errors.
However, I don't see a reason (at least for now) to export this function,
therefore making it static in this PR.
The implementation is not as efficient as for native Linux platform due
to lack of FUTEX_REQUEUE-like system call in WASI.
For now we wake all the waiters which is inefficient; if that becomes
a bottleneck, I suggest we'll revisit the implementation.
[POSIX semaphores] come in two forms: named and unnamed. Roughly, named
semaphores use files to implement locking across processes; unnamed
semaphores use a shared memory region to implement locking across
threads in the same process. Since WASI currently has no process concept
(and it is relatively unclear how to map the WASI files as shared
memory), only the unnamed semaphores are supported by this changed. This
means that `sem_open`, `sem_close`, and `sem_unlink` will not available
to programs compiled with a threads-enabled `wasi-libc`.
[POSIX semaphores]: https://man7.org/linux/man-pages/man7/sem_overview.7.html
This change adds pthread's mutex support to the `THREAD_MODEL=posix`
build of wasi-libc. Some less-common features are unsupported and
documented here:
- mutex robust lists are disabled and their use will return a runtime
error; currently WASI does not support the concept of multiple
processes so maintaining robust mutexes across processes does not yet
make sense in wasi-libc
- timed locks with priority inheritance (PI) are disabled and will act
as any other mutex; this feature is related to task priorities which
is not yet relevant in the WASI ecosystem (see [priority-inheritance
futexes](https://man7.org/linux/man-pages/man2/futex.2.html))
- thread cancellation is ignored; this feature is difficult to support
and @sunfishcode would likely want to discuss this before adding it at
some later time.
* Fixes for the THREAD_MODEL=posix build
* Fix expected symbols from previous commit
* Enable `lock` in `random.c` when threads are enabled
This uses the `_REENTRANT` definition to indicate when the `lock` should
be available.
* Disable `aio.h` when compiling for threads
In talking to @sunfishcode about `aio.h`, this functionality is not yet
a primary concern (it was already disabled in the default,
single-threaded mode). Additionally, this change adds expectation lines
for the new symbols/includes added and removed by `pthread.h`.
This change was reached by running:
```console
$ git diff --no-index expected/wasm32-wasi sysroot/share/wasm32-wasi > patch.diff
# replace "sysroot/share" with "expected" in `patch.diff`
$ git apply patch.diff --reject
# manually fix any rejections
```
* Specify the TLS model until LLVM 15 is released
The `-ftls-model` configuration can be removed once https://reviews.llvm.org/D130053 makes its way into an upstream release.
* Rename `__wasi_libc_pthread_self` to `__wasilibc_pthread_self`
The symbol is still undefined, though.
* Add different sets of expected output based on THREAD_MODEL
* Re-add trailing whitespace to `predefined-macros.txt`
@sbc100 wanted to retain the whitespace trailing after certain
predefined macro lines. This change restores that whitespace from
upstream and re-generates the POSIX version using the following command:
```console
$ git diff --no-index expected/wasm32-wasi/posix/predefined-macros.txt sysroot/share/wasm32-wasi/predefined-macros.txt | sed 's/sysroot\/share\/wasm32-wasi/expected\/wasm32-wasi\/posix/' | git apply
```
* Protect `preopens.c` against concurrent access
* Only build thread-capable wasi-libc on latest version of Clang
* Use `thrd_sleep` from MUSL instead of aliasing `nanosleep`
* Define `pthread_setcancelstate` in `THREAD_MODEL=posix` builds
There are other options here (e.g., always define the `pthread_*`
symbols with stubs) but until we discuss that this is an intermediate
working step.
* Define a Wasm global to store `pthread_self`
* Remove `g_needs_dynamic_alloc` global
* Document the state of pthread support
* review: de-duplicate symbols based on #314
* review: only define `__wasilibc_cwd_{un}lock` when needed
* review: add #ifdefs to `__pthread_setcancelstate`
* review: add additional #ifdefs to `pthread_self.c`
* review: put lock definition behind #ifdef _REENTRANT
* review: remove pthread_setcancelstate.c
* review: re-fix indentation
* review: alias __clock_nanosleep in bottom half
* review: remove extra line
Co-authored-by: Sam Clegg <sbc@chromium.org>
* Delete several blocks of unused code.
Delete several pieces of code from libc-bottom-half/cloudlibc that aren't in
use on wasi-libc.
* Delete more of `_CLOCK_PROCESS_CPUTIME_ID` or `_CLOCK_THREAD_CPUTIME_ID`.
* Add a `getpagesize` function.
This adds a `getpagesize` function. This interface is deprecated in POSIX,
but it's sufficiently widely used and not problematic in practice.
* Use musl's `getpagesize`.
* Enable the `getpagesize` declaration in unistd.h.
* Remove support for `__original_main`.
This was used in old LLVM versions. Recent LLVM versions all emit either
`__main_void` or `__main_argv_argc`, so we can use those directly.
* Update the CI to use LLVM 14.0.0.
Since the socket address of the accepted socket is unknown,
all bytes are set to zero and the length is truncated to the size
of the generic `struct sockaddr`.
Signed-off-by: Harald Hoyer <harald@profian.com>
The WASI signal constants and proc_raise function were removed in the
latest [ephemeral], which had been scheduled to be in the next snapshot,
however WASI itself is now transitioning away from the snapshot system.
WASI libc will also be transitioning to updated wit specs once they're
ready, however until that time, we can make the simple change of
removing these signal constants to avoid confusion.
Fixes#271.
Fixes#272.
[ephemeral]: https://github.com/WebAssembly/WASI/tree/main/phases/ephemeral/witx
Add a `__wasilibc_deinit_environ` function which clears the current
environment variable state to the state where next time the environment
variable functions are called, they'll reinitialize the environment.
And add a `__wasilibc_maybe_reinitialize_environ_eagerly` function to
reinitialize the environment variable state if `environ` or `_environ`
are needed.
These functions are needed by wizer to be able to suspend and resume
a program and have it read new environment variables from the host
environment; see bytecodealliance/wizer#8 for background.
Upcoming WASI snapshots omit the `PROCESS_CPUTIME` clock, since WASI has
no inherent concept of processes, and since implementations which don't
use a process for each instance don't have a way to implement it
efficiently.
However, `clock`, `times`, and `getrusage` are useful functions, so
provide optional emulated version of them, using the `MONOTONIC` clock.
This means these implementations will measure not just the program's
own CPU time, but also time spent suspended while other programs are
running.
Due to this difference in behavior, put these implementations behind
a flag. Users must pass `-D_WASI_EMULATED_PROCESS_CLOCK` and link with
`-lwasi-emulated-process-clocks` to enable them.
* Update to the next version of the `witx` crate
* Generate adapter functions instead of simply a header file to have a
place where adapter code can go.
* Implement adapters in terms of the instructions that the `witx` crate
tells us about.
* Update the interface of functions to what `witx` expects, notably
string arguments are now only taken as `char*` and `strlen` happens in
the adapter function.
* Update defined/predefined/undefined symbol lists for types that have
been updated.
Some precise generated code has changed but the actual APIs should all
be the same except for the change to not take the length of the string
in the raw WASI call, since idiomatically C doesn't pass the length of
strings around.
Eventually it's expected that the shim functions, while sometimes not
necessary today, will implement more checks and more conversions as
necessary for new APIs.
* Actually update witx submodule
* Comment how to regenerate files
* Tweak name of actual function imports
Make it a bit clearer that they're the ones that we're importing and
calling.
* Update submodule to point to WebAssembly
AT_FDCWD is a special constant in POSIX that can be passed to *at
functions to indicate the current working directory. Since the
current working directory is emulated in wasi libc, add emulated
AT_FDCWD support as well.
Fixes#42.
See the WHATSNEW file for details. WASI libc currently uses a separate
malloc, so the new mallocng is not currently used.
This includes a few new custom changes to disable code for handling
directed rounding modes. Wasm doesn't have directed rounding modes,
so disabling this code size saves code size, something the WASI libc
project cares about!
* Add basic emulation of getcwd/chdir
This commit adds basic emulation of a current working directory to
wasi-libc. The `getcwd` and `chdir` symbols are now implemented and
available for use. The `getcwd` implementation is pretty simple in that
it just copies out of a new global, `__wasilibc_cwd`, which defaults to
`"/"`. The `chdir` implementation is much more involved and has more
ramification, however.
A new function, `make_absolute`, was added to the preopens object. Paths
stored in the preopen table are now always stored as absolute paths
instead of relative paths, and initial relative paths are interpreted as
being relative to `/`. Looking up a path to preopen now always turns it
into an absolute path, relative to the current working directory, and an
appropriate path is then returned.
The signature of `__wasilibc_find_relpath` has changed as well. It now
returns two path components, one for the absolute part and one for the
relative part. Additionally the relative part is always dynamically
allocated since it may no longer be a substring of the original input
path.
This has been tested lightly against the Rust standard library so far,
but I'm not a regular C developer so there's likely a few things to
improve!
* Amortize mallocs made in syscalls
* Avoid size bloat on programs that don't use `chdir`
* Add threading compat
* Collect `link`/`renameat` second path lookup
* Update comments about chdir.c in makefile
* Move definition of `__wasilibc_find_relpath_alloc` to header
* Expand comments
* Document the format of strings a bit more
* Fixup a few issues in path logic
* Fix GitHub Actions