mirror of
https://git.proxmox.com/git/wasi-libc
synced 2025-10-05 08:25:51 +00:00
Fix make THREAD_MODEL=posix
(#311)
* 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>
This commit is contained in:
parent
69031b6370
commit
dcd28cf8f6
8
.github/workflows/main.yml
vendored
8
.github/workflows/main.yml
vendored
@ -66,6 +66,14 @@ jobs:
|
|||||||
name: ${{ format( 'sysroot-{0}.tgz', matrix.os) }}
|
name: ${{ format( 'sysroot-{0}.tgz', matrix.os) }}
|
||||||
path: sysroot
|
path: sysroot
|
||||||
|
|
||||||
|
- name: Build libc + threads
|
||||||
|
# Only build the thread-capable wasi-libc in the latest supported Clang
|
||||||
|
# version; the earliest version does not have all necessary builtins
|
||||||
|
# (e.g., `__builtin_wasm_memory_atomic_notify`).
|
||||||
|
if: matrix.clang_version != '10.0.0'
|
||||||
|
shell: bash
|
||||||
|
run: make -j4 THREAD_MODEL=posix
|
||||||
|
|
||||||
# Disable the headerstest job for now, while WASI transitions from the
|
# Disable the headerstest job for now, while WASI transitions from the
|
||||||
# witx snapshots to wit proposals, and we have a few manual edits to the
|
# witx snapshots to wit proposals, and we have a few manual edits to the
|
||||||
# generated header to make life easier for folks.
|
# generated header to make life easier for folks.
|
||||||
|
15
Makefile
15
Makefile
@ -13,7 +13,7 @@ EXTRA_CFLAGS ?= -O2 -DNDEBUG
|
|||||||
SYSROOT ?= $(CURDIR)/sysroot
|
SYSROOT ?= $(CURDIR)/sysroot
|
||||||
# A directory to install to for "make install".
|
# A directory to install to for "make install".
|
||||||
INSTALL_DIR ?= /usr/local
|
INSTALL_DIR ?= /usr/local
|
||||||
# single or posix
|
# single or posix; note that pthread support is still a work-in-progress.
|
||||||
THREAD_MODEL ?= single
|
THREAD_MODEL ?= single
|
||||||
# dlmalloc or none
|
# dlmalloc or none
|
||||||
MALLOC_IMPL ?= dlmalloc
|
MALLOC_IMPL ?= dlmalloc
|
||||||
@ -147,6 +147,7 @@ LIBC_TOP_HALF_MUSL_SOURCES = \
|
|||||||
unistd/posix_close.c \
|
unistd/posix_close.c \
|
||||||
stat/futimesat.c \
|
stat/futimesat.c \
|
||||||
legacy/getpagesize.c \
|
legacy/getpagesize.c \
|
||||||
|
thread/thrd_sleep.c \
|
||||||
) \
|
) \
|
||||||
$(filter-out %/procfdname.c %/syscall.c %/syscall_ret.c %/vdso.c %/version.c, \
|
$(filter-out %/procfdname.c %/syscall.c %/syscall_ret.c %/vdso.c %/version.c, \
|
||||||
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal/*.c)) \
|
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal/*.c)) \
|
||||||
@ -185,6 +186,7 @@ LIBC_TOP_HALF_MUSL_SOURCES = \
|
|||||||
%/cimagf.c %/cimag.c %cimagl.c, \
|
%/cimagf.c %/cimag.c %cimagl.c, \
|
||||||
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/complex/*.c)) \
|
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/complex/*.c)) \
|
||||||
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/crypt/*.c)
|
$(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/crypt/*.c)
|
||||||
|
|
||||||
MUSL_PRINTSCAN_SOURCES = \
|
MUSL_PRINTSCAN_SOURCES = \
|
||||||
$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal/floatscan.c \
|
$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal/floatscan.c \
|
||||||
$(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdio/vfprintf.c \
|
$(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdio/vfprintf.c \
|
||||||
@ -227,7 +229,9 @@ ifeq ($(THREAD_MODEL), single)
|
|||||||
CFLAGS += -mthread-model single
|
CFLAGS += -mthread-model single
|
||||||
endif
|
endif
|
||||||
ifeq ($(THREAD_MODEL), posix)
|
ifeq ($(THREAD_MODEL), posix)
|
||||||
CFLAGS += -mthread-model posix -pthread
|
# Specify the tls-model until LLVM 15 is released (which should contain
|
||||||
|
# https://reviews.llvm.org/D130053).
|
||||||
|
CFLAGS += -mthread-model posix -pthread -ftls-model=local-exec
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Expose the public headers to the implementation. We use `-isystem` for
|
# Expose the public headers to the implementation. We use `-isystem` for
|
||||||
@ -356,11 +360,12 @@ MUSL_OMIT_HEADERS += \
|
|||||||
"netinet/ether.h" \
|
"netinet/ether.h" \
|
||||||
"sys/timerfd.h" \
|
"sys/timerfd.h" \
|
||||||
"libintl.h" \
|
"libintl.h" \
|
||||||
"sys/sysmacros.h"
|
"sys/sysmacros.h" \
|
||||||
|
"aio.h"
|
||||||
|
|
||||||
ifeq ($(THREAD_MODEL), single)
|
ifeq ($(THREAD_MODEL), single)
|
||||||
# Remove headers not supported in single-threaded mode.
|
# Remove headers not supported in single-threaded mode.
|
||||||
MUSL_OMIT_HEADERS += "aio.h" "pthread.h"
|
MUSL_OMIT_HEADERS += "pthread.h"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
default: finish
|
default: finish
|
||||||
@ -595,7 +600,7 @@ check-symbols: startup_files libc
|
|||||||
|
|
||||||
# Check that the computed metadata matches the expected metadata.
|
# Check that the computed metadata matches the expected metadata.
|
||||||
# This ignores whitespace because on Windows the output has CRLF line endings.
|
# This ignores whitespace because on Windows the output has CRLF line endings.
|
||||||
diff -wur "$(CURDIR)/expected/$(MULTIARCH_TRIPLE)" "$(SYSROOT_SHARE)"
|
diff -wur "$(CURDIR)/expected/$(MULTIARCH_TRIPLE)/$(THREAD_MODEL)" "$(SYSROOT_SHARE)"
|
||||||
|
|
||||||
install: finish
|
install: finish
|
||||||
mkdir -p "$(INSTALL_DIR)"
|
mkdir -p "$(INSTALL_DIR)"
|
||||||
|
@ -7,7 +7,8 @@ environment variables, program startup, and many other APIs.
|
|||||||
|
|
||||||
WASI Libc is sufficiently stable and usable for many purposes, as most of the
|
WASI Libc is sufficiently stable and usable for many purposes, as most of the
|
||||||
POSIX-compatible APIs are stable, though it is continuing to evolve to better
|
POSIX-compatible APIs are stable, though it is continuing to evolve to better
|
||||||
align with wasm and WASI.
|
align with wasm and WASI. For example, pthread support is still a work in
|
||||||
|
progress.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
1210
expected/wasm32-wasi/posix/defined-symbols.txt
Normal file
1210
expected/wasm32-wasi/posix/defined-symbols.txt
Normal file
File diff suppressed because it is too large
Load Diff
171
expected/wasm32-wasi/posix/include-all.c
Normal file
171
expected/wasm32-wasi/posix/include-all.c
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
#include <__errno.h>
|
||||||
|
#include <__errno_values.h>
|
||||||
|
#include <__fd_set.h>
|
||||||
|
#include <__function___isatty.h>
|
||||||
|
#include <__functions_malloc.h>
|
||||||
|
#include <__functions_memcpy.h>
|
||||||
|
#include <__header_dirent.h>
|
||||||
|
#include <__header_fcntl.h>
|
||||||
|
#include <__header_inttypes.h>
|
||||||
|
#include <__header_netinet_in.h>
|
||||||
|
#include <__header_poll.h>
|
||||||
|
#include <__header_stdlib.h>
|
||||||
|
#include <__header_string.h>
|
||||||
|
#include <__header_sys_ioctl.h>
|
||||||
|
#include <__header_sys_resource.h>
|
||||||
|
#include <__header_sys_socket.h>
|
||||||
|
#include <__header_sys_stat.h>
|
||||||
|
#include <__header_time.h>
|
||||||
|
#include <__header_unistd.h>
|
||||||
|
#include <__macro_FD_SETSIZE.h>
|
||||||
|
#include <__macro_PAGESIZE.h>
|
||||||
|
#include <__mode_t.h>
|
||||||
|
#include <__seek.h>
|
||||||
|
#include <__struct_dirent.h>
|
||||||
|
#include <__struct_in6_addr.h>
|
||||||
|
#include <__struct_in_addr.h>
|
||||||
|
#include <__struct_iovec.h>
|
||||||
|
#include <__struct_msghdr.h>
|
||||||
|
#include <__struct_pollfd.h>
|
||||||
|
#include <__struct_rusage.h>
|
||||||
|
#include <__struct_sockaddr.h>
|
||||||
|
#include <__struct_sockaddr_in.h>
|
||||||
|
#include <__struct_sockaddr_in6.h>
|
||||||
|
#include <__struct_sockaddr_storage.h>
|
||||||
|
#include <__struct_sockaddr_un.h>
|
||||||
|
#include <__struct_stat.h>
|
||||||
|
#include <__struct_timespec.h>
|
||||||
|
#include <__struct_timeval.h>
|
||||||
|
#include <__struct_tm.h>
|
||||||
|
#include <__struct_tms.h>
|
||||||
|
#include <__typedef_DIR.h>
|
||||||
|
#include <__typedef_blkcnt_t.h>
|
||||||
|
#include <__typedef_blksize_t.h>
|
||||||
|
#include <__typedef_clock_t.h>
|
||||||
|
#include <__typedef_clockid_t.h>
|
||||||
|
#include <__typedef_dev_t.h>
|
||||||
|
#include <__typedef_fd_set.h>
|
||||||
|
#include <__typedef_gid_t.h>
|
||||||
|
#include <__typedef_in_addr_t.h>
|
||||||
|
#include <__typedef_in_port_t.h>
|
||||||
|
#include <__typedef_ino_t.h>
|
||||||
|
#include <__typedef_mode_t.h>
|
||||||
|
#include <__typedef_nfds_t.h>
|
||||||
|
#include <__typedef_nlink_t.h>
|
||||||
|
#include <__typedef_off_t.h>
|
||||||
|
#include <__typedef_sa_family_t.h>
|
||||||
|
#include <__typedef_sigset_t.h>
|
||||||
|
#include <__typedef_socklen_t.h>
|
||||||
|
#include <__typedef_ssize_t.h>
|
||||||
|
#include <__typedef_suseconds_t.h>
|
||||||
|
#include <__typedef_time_t.h>
|
||||||
|
#include <__typedef_uid_t.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <ar.h>
|
||||||
|
#include <arpa/ftp.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <arpa/nameser.h>
|
||||||
|
#include <arpa/nameser_compat.h>
|
||||||
|
#include <arpa/telnet.h>
|
||||||
|
#include <arpa/tftp.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <byteswap.h>
|
||||||
|
#include <complex.h>
|
||||||
|
#include <cpio.h>
|
||||||
|
#include <crypt.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <endian.h>
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <features.h>
|
||||||
|
#include <fenv.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <fmtmsg.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <ftw.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <glob.h>
|
||||||
|
#include <iconv.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <iso646.h>
|
||||||
|
#include <langinfo.h>
|
||||||
|
#include <libgen.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <monetary.h>
|
||||||
|
#include <mqueue.h>
|
||||||
|
#include <netinet/icmp6.h>
|
||||||
|
#include <netinet/igmp.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/in_systm.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <netinet/ip6.h>
|
||||||
|
#include <netinet/ip_icmp.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
#include <netinet/udp.h>
|
||||||
|
#include <netpacket/packet.h>
|
||||||
|
#include <nl_types.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <regex.h>
|
||||||
|
#include <sched.h>
|
||||||
|
#include <search.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <stdalign.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdc-predef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdio_ext.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdnoreturn.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include <stropts.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <sys/eventfd.h>
|
||||||
|
#include <sys/fcntl.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <sys/random.h>
|
||||||
|
#include <sys/reg.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/stropts.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/sysinfo.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
#include <sys/timex.h>
|
||||||
|
#include <sys/ttydefaults.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
#include <sysexits.h>
|
||||||
|
#include <tar.h>
|
||||||
|
#include <tgmath.h>
|
||||||
|
#include <threads.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <uchar.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <utime.h>
|
||||||
|
#include <values.h>
|
||||||
|
#include <wasi/api.h>
|
||||||
|
#include <wasi/libc-environ.h>
|
||||||
|
#include <wasi/libc-find-relpath.h>
|
||||||
|
#include <wasi/libc-nocwd.h>
|
||||||
|
#include <wasi/libc.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <wctype.h>
|
3396
expected/wasm32-wasi/posix/predefined-macros.txt
Normal file
3396
expected/wasm32-wasi/posix/predefined-macros.txt
Normal file
File diff suppressed because it is too large
Load Diff
75
expected/wasm32-wasi/posix/undefined-symbols.txt
Normal file
75
expected/wasm32-wasi/posix/undefined-symbols.txt
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
__addtf3
|
||||||
|
__divtf3
|
||||||
|
__eqtf2
|
||||||
|
__extenddftf2
|
||||||
|
__extendsftf2
|
||||||
|
__fixtfdi
|
||||||
|
__fixtfsi
|
||||||
|
__fixunstfsi
|
||||||
|
__floatsitf
|
||||||
|
__floatunsitf
|
||||||
|
__getf2
|
||||||
|
__gttf2
|
||||||
|
__heap_base
|
||||||
|
__imported_wasi_snapshot_preview1_args_get
|
||||||
|
__imported_wasi_snapshot_preview1_args_sizes_get
|
||||||
|
__imported_wasi_snapshot_preview1_clock_res_get
|
||||||
|
__imported_wasi_snapshot_preview1_clock_time_get
|
||||||
|
__imported_wasi_snapshot_preview1_environ_get
|
||||||
|
__imported_wasi_snapshot_preview1_environ_sizes_get
|
||||||
|
__imported_wasi_snapshot_preview1_fd_advise
|
||||||
|
__imported_wasi_snapshot_preview1_fd_allocate
|
||||||
|
__imported_wasi_snapshot_preview1_fd_close
|
||||||
|
__imported_wasi_snapshot_preview1_fd_datasync
|
||||||
|
__imported_wasi_snapshot_preview1_fd_fdstat_get
|
||||||
|
__imported_wasi_snapshot_preview1_fd_fdstat_set_flags
|
||||||
|
__imported_wasi_snapshot_preview1_fd_fdstat_set_rights
|
||||||
|
__imported_wasi_snapshot_preview1_fd_filestat_get
|
||||||
|
__imported_wasi_snapshot_preview1_fd_filestat_set_size
|
||||||
|
__imported_wasi_snapshot_preview1_fd_filestat_set_times
|
||||||
|
__imported_wasi_snapshot_preview1_fd_pread
|
||||||
|
__imported_wasi_snapshot_preview1_fd_prestat_dir_name
|
||||||
|
__imported_wasi_snapshot_preview1_fd_prestat_get
|
||||||
|
__imported_wasi_snapshot_preview1_fd_pwrite
|
||||||
|
__imported_wasi_snapshot_preview1_fd_read
|
||||||
|
__imported_wasi_snapshot_preview1_fd_readdir
|
||||||
|
__imported_wasi_snapshot_preview1_fd_renumber
|
||||||
|
__imported_wasi_snapshot_preview1_fd_seek
|
||||||
|
__imported_wasi_snapshot_preview1_fd_sync
|
||||||
|
__imported_wasi_snapshot_preview1_fd_tell
|
||||||
|
__imported_wasi_snapshot_preview1_fd_write
|
||||||
|
__imported_wasi_snapshot_preview1_path_create_directory
|
||||||
|
__imported_wasi_snapshot_preview1_path_filestat_get
|
||||||
|
__imported_wasi_snapshot_preview1_path_filestat_set_times
|
||||||
|
__imported_wasi_snapshot_preview1_path_link
|
||||||
|
__imported_wasi_snapshot_preview1_path_open
|
||||||
|
__imported_wasi_snapshot_preview1_path_readlink
|
||||||
|
__imported_wasi_snapshot_preview1_path_remove_directory
|
||||||
|
__imported_wasi_snapshot_preview1_path_rename
|
||||||
|
__imported_wasi_snapshot_preview1_path_symlink
|
||||||
|
__imported_wasi_snapshot_preview1_path_unlink_file
|
||||||
|
__imported_wasi_snapshot_preview1_poll_oneoff
|
||||||
|
__imported_wasi_snapshot_preview1_proc_exit
|
||||||
|
__imported_wasi_snapshot_preview1_random_get
|
||||||
|
__imported_wasi_snapshot_preview1_sched_yield
|
||||||
|
__imported_wasi_snapshot_preview1_sock_accept
|
||||||
|
__imported_wasi_snapshot_preview1_sock_recv
|
||||||
|
__imported_wasi_snapshot_preview1_sock_send
|
||||||
|
__imported_wasi_snapshot_preview1_sock_shutdown
|
||||||
|
__letf2
|
||||||
|
__lock
|
||||||
|
__lockfile
|
||||||
|
__lttf2
|
||||||
|
__main_argc_argv
|
||||||
|
__netf2
|
||||||
|
__stack_pointer
|
||||||
|
__subtf3
|
||||||
|
__tls_base
|
||||||
|
__trunctfdf2
|
||||||
|
__trunctfsf2
|
||||||
|
__unlock
|
||||||
|
__unlockfile
|
||||||
|
__unordtf2
|
||||||
|
__wasilibc_pthread_self
|
||||||
|
__wasm_call_ctors
|
||||||
|
pthread_setcancelstate
|
@ -18,6 +18,7 @@ __c_dot_utf8_locale
|
|||||||
__c_locale
|
__c_locale
|
||||||
__clock
|
__clock
|
||||||
__clock_gettime
|
__clock_gettime
|
||||||
|
__clock_nanosleep
|
||||||
__cos
|
__cos
|
||||||
__cosdf
|
__cosdf
|
||||||
__cosl
|
__cosl
|
||||||
@ -1082,6 +1083,7 @@ tfind
|
|||||||
tgamma
|
tgamma
|
||||||
tgammaf
|
tgammaf
|
||||||
tgammal
|
tgammal
|
||||||
|
thrd_sleep
|
||||||
time
|
time
|
||||||
timegm
|
timegm
|
||||||
times
|
times
|
@ -33,3 +33,5 @@ int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp,
|
|||||||
__wasi_errno_t error = __wasi_poll_oneoff(&sub, &ev, 1, &nevents);
|
__wasi_errno_t error = __wasi_poll_oneoff(&sub, &ev, 1, &nevents);
|
||||||
return error == 0 && ev.error == 0 ? 0 : ENOTSUP;
|
return error == 0 && ev.error == 0 ? 0 : ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
weak_alias(clock_nanosleep, __clock_nanosleep);
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
// SPDX-License-Identifier: BSD-2-Clause
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <threads.h>
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <_/cdefs.h>
|
|
||||||
|
|
||||||
int nanosleep(const struct timespec *rqtp, struct timespec *rem) {
|
int nanosleep(const struct timespec *rqtp, struct timespec *rem) {
|
||||||
int error = clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rem);
|
int error = clock_nanosleep(CLOCK_REALTIME, 0, rqtp, rem);
|
||||||
@ -15,7 +13,3 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rem) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_REENTRANT)
|
|
||||||
__strong_reference(nanosleep, thrd_sleep);
|
|
||||||
#endif
|
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
#include <wasi/libc.h>
|
#include <wasi/libc.h>
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
#ifdef _REENTRANT
|
||||||
#error "chdir doesn't yet support multiple threads"
|
void __wasilibc_cwd_lock(void);
|
||||||
|
void __wasilibc_cwd_unlock(void);
|
||||||
|
#else
|
||||||
|
#define __wasilibc_cwd_lock() (void)0
|
||||||
|
#define __wasilibc_cwd_unlock() (void)0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char *__wasilibc_cwd;
|
extern char *__wasilibc_cwd;
|
||||||
static int __wasilibc_cwd_mallocd = 0;
|
static int __wasilibc_cwd_mallocd = 0;
|
||||||
|
|
||||||
@ -60,8 +63,10 @@ int chdir(const char *path)
|
|||||||
|
|
||||||
// And set our new malloc'd buffer into the global cwd, freeing the
|
// And set our new malloc'd buffer into the global cwd, freeing the
|
||||||
// previous one if necessary.
|
// previous one if necessary.
|
||||||
|
__wasilibc_cwd_lock();
|
||||||
char *prev_cwd = __wasilibc_cwd;
|
char *prev_cwd = __wasilibc_cwd;
|
||||||
__wasilibc_cwd = new_cwd;
|
__wasilibc_cwd = new_cwd;
|
||||||
|
__wasilibc_cwd_unlock();
|
||||||
if (__wasilibc_cwd_mallocd)
|
if (__wasilibc_cwd_mallocd)
|
||||||
free(prev_cwd);
|
free(prev_cwd);
|
||||||
__wasilibc_cwd_mallocd = 1;
|
__wasilibc_cwd_mallocd = 1;
|
||||||
@ -77,11 +82,13 @@ static const char *make_absolute(const char *path) {
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _REENTRANT
|
||||||
// If the path is empty, or points to the current directory, then return
|
// If the path is empty, or points to the current directory, then return
|
||||||
// the current directory.
|
// the current directory.
|
||||||
if (path[0] == 0 || !strcmp(path, ".") || !strcmp(path, "./")) {
|
if (path[0] == 0 || !strcmp(path, ".") || !strcmp(path, "./")) {
|
||||||
return __wasilibc_cwd;
|
return __wasilibc_cwd;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// If the path starts with `./` then we won't be appending that to the cwd.
|
// If the path starts with `./` then we won't be appending that to the cwd.
|
||||||
if (path[0] == '.' && path[1] == '/')
|
if (path[0] == '.' && path[1] == '/')
|
||||||
@ -90,18 +97,30 @@ static const char *make_absolute(const char *path) {
|
|||||||
// Otherwise we'll take the current directory, add a `/`, and then add the
|
// Otherwise we'll take the current directory, add a `/`, and then add the
|
||||||
// input `path`. Note that this doesn't do any normalization (like removing
|
// input `path`. Note that this doesn't do any normalization (like removing
|
||||||
// `/./`).
|
// `/./`).
|
||||||
|
__wasilibc_cwd_lock();
|
||||||
size_t cwd_len = strlen(__wasilibc_cwd);
|
size_t cwd_len = strlen(__wasilibc_cwd);
|
||||||
size_t path_len = strlen(path);
|
size_t path_len = path ? strlen(path) : 0;
|
||||||
|
__wasilibc_cwd_unlock();
|
||||||
int need_slash = __wasilibc_cwd[cwd_len - 1] == '/' ? 0 : 1;
|
int need_slash = __wasilibc_cwd[cwd_len - 1] == '/' ? 0 : 1;
|
||||||
size_t alloc_len = cwd_len + path_len + 1 + need_slash;
|
size_t alloc_len = cwd_len + path_len + 1 + need_slash;
|
||||||
if (alloc_len > make_absolute_len) {
|
if (alloc_len > make_absolute_len) {
|
||||||
char *tmp = realloc(make_absolute_buf, alloc_len);
|
char *tmp = realloc(make_absolute_buf, alloc_len);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL) {
|
||||||
|
__wasilibc_cwd_unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
make_absolute_buf = tmp;
|
make_absolute_buf = tmp;
|
||||||
make_absolute_len = alloc_len;
|
make_absolute_len = alloc_len;
|
||||||
}
|
}
|
||||||
strcpy(make_absolute_buf, __wasilibc_cwd);
|
strcpy(make_absolute_buf, __wasilibc_cwd);
|
||||||
|
__wasilibc_cwd_unlock();
|
||||||
|
|
||||||
|
#ifdef _REENTRANT
|
||||||
|
if (path[0] == 0 || !strcmp(path, ".") || !strcmp(path, "./")) {
|
||||||
|
return make_absolute_buf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (need_slash)
|
if (need_slash)
|
||||||
strcpy(make_absolute_buf + cwd_len, "/");
|
strcpy(make_absolute_buf + cwd_len, "/");
|
||||||
strcpy(make_absolute_buf + cwd_len + need_slash, path);
|
strcpy(make_absolute_buf + cwd_len + need_slash, path);
|
||||||
|
@ -1,30 +1,39 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "lock.h"
|
||||||
// For threads this needs to synchronize with chdir
|
|
||||||
#ifdef _REENTRANT
|
|
||||||
#error "getcwd doesn't yet support multiple threads"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
char *__wasilibc_cwd = "/";
|
char *__wasilibc_cwd = "/";
|
||||||
|
|
||||||
|
#ifdef _REENTRANT
|
||||||
|
static volatile int lock[1];
|
||||||
|
void __wasilibc_cwd_lock(void) { LOCK(lock); }
|
||||||
|
void __wasilibc_cwd_unlock(void) { UNLOCK(lock); }
|
||||||
|
#else
|
||||||
|
#define __wasilibc_cwd_lock() (void)0
|
||||||
|
#define __wasilibc_cwd_unlock() (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
char *getcwd(char *buf, size_t size)
|
char *getcwd(char *buf, size_t size)
|
||||||
{
|
{
|
||||||
|
__wasilibc_cwd_lock();
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
buf = strdup(__wasilibc_cwd);
|
buf = strdup(__wasilibc_cwd);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
|
__wasilibc_cwd_unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
size_t len = strlen(__wasilibc_cwd);
|
size_t len = strlen(__wasilibc_cwd);
|
||||||
if (size < len + 1) {
|
if (size < len + 1) {
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
|
__wasilibc_cwd_unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy(buf, __wasilibc_cwd);
|
strcpy(buf, __wasilibc_cwd);
|
||||||
}
|
}
|
||||||
|
__wasilibc_cwd_unlock();
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
#include <wasi/api.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <wasi/api.h>
|
||||||
#ifdef _REENTRANT
|
|
||||||
#error With threads support, getentropy is not intended to be a cancellation point.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int __getentropy(void *buffer, size_t len) {
|
int __getentropy(void *buffer, size_t len) {
|
||||||
if (len > 256) {
|
if (len > 256) {
|
||||||
|
@ -2,14 +2,11 @@
|
|||||||
//! environment, with associated path prefixes, which can be used to map
|
//! environment, with associated path prefixes, which can be used to map
|
||||||
//! absolute paths to capabilities with relative paths.
|
//! absolute paths to capabilities with relative paths.
|
||||||
|
|
||||||
#ifdef _REENTRANT
|
|
||||||
#error "__wasilibc_register_preopened_fd doesn't yet support multiple threads"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <lock.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -32,6 +29,12 @@ static preopen *preopens;
|
|||||||
static size_t num_preopens;
|
static size_t num_preopens;
|
||||||
static size_t preopen_capacity;
|
static size_t preopen_capacity;
|
||||||
|
|
||||||
|
/// Access to the the above preopen must be protected in the presence of
|
||||||
|
/// threads.
|
||||||
|
#ifdef _REENTRANT
|
||||||
|
static volatile int lock[1];
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#define assert_invariants() // assertions disabled
|
#define assert_invariants() // assertions disabled
|
||||||
#else
|
#else
|
||||||
@ -55,6 +58,7 @@ static void assert_invariants(void) {
|
|||||||
|
|
||||||
/// Allocate space for more preopens. Returns 0 on success and -1 on failure.
|
/// Allocate space for more preopens. Returns 0 on success and -1 on failure.
|
||||||
static int resize(void) {
|
static int resize(void) {
|
||||||
|
LOCK(lock);
|
||||||
size_t start_capacity = 4;
|
size_t start_capacity = 4;
|
||||||
size_t old_capacity = preopen_capacity;
|
size_t old_capacity = preopen_capacity;
|
||||||
size_t new_capacity = old_capacity == 0 ? start_capacity : old_capacity * 2;
|
size_t new_capacity = old_capacity == 0 ? start_capacity : old_capacity * 2;
|
||||||
@ -62,6 +66,7 @@ static int resize(void) {
|
|||||||
preopen *old_preopens = preopens;
|
preopen *old_preopens = preopens;
|
||||||
preopen *new_preopens = calloc(sizeof(preopen), new_capacity);
|
preopen *new_preopens = calloc(sizeof(preopen), new_capacity);
|
||||||
if (new_preopens == NULL)
|
if (new_preopens == NULL)
|
||||||
|
UNLOCK(lock);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(new_preopens, old_preopens, num_preopens * sizeof(preopen));
|
memcpy(new_preopens, old_preopens, num_preopens * sizeof(preopen));
|
||||||
@ -70,6 +75,7 @@ static int resize(void) {
|
|||||||
free(old_preopens);
|
free(old_preopens);
|
||||||
|
|
||||||
assert_invariants();
|
assert_invariants();
|
||||||
|
UNLOCK(lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +103,8 @@ static const char *strip_prefixes(const char *path) {
|
|||||||
///
|
///
|
||||||
/// This function takes ownership of `prefix`.
|
/// This function takes ownership of `prefix`.
|
||||||
static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix) {
|
static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix) {
|
||||||
|
LOCK(lock);
|
||||||
|
|
||||||
// Check preconditions.
|
// Check preconditions.
|
||||||
assert_invariants();
|
assert_invariants();
|
||||||
assert(fd != AT_FDCWD);
|
assert(fd != AT_FDCWD);
|
||||||
@ -104,14 +112,17 @@ static int internal_register_preopened_fd(__wasi_fd_t fd, const char *relprefix)
|
|||||||
assert(relprefix != NULL);
|
assert(relprefix != NULL);
|
||||||
|
|
||||||
if (num_preopens == preopen_capacity && resize() != 0)
|
if (num_preopens == preopen_capacity && resize() != 0)
|
||||||
|
UNLOCK(lock);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
char *prefix = strdup(strip_prefixes(relprefix));
|
char *prefix = strdup(strip_prefixes(relprefix));
|
||||||
if (prefix == NULL)
|
if (prefix == NULL)
|
||||||
|
UNLOCK(lock);
|
||||||
return -1;
|
return -1;
|
||||||
preopens[num_preopens++] = (preopen) { prefix, fd, };
|
preopens[num_preopens++] = (preopen) { prefix, fd, };
|
||||||
|
|
||||||
assert_invariants();
|
assert_invariants();
|
||||||
|
UNLOCK(lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,6 +177,7 @@ int __wasilibc_find_abspath(const char *path,
|
|||||||
// recently added preopens take precedence over less recently addded ones.
|
// recently added preopens take precedence over less recently addded ones.
|
||||||
size_t match_len = 0;
|
size_t match_len = 0;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
LOCK(lock);
|
||||||
for (size_t i = num_preopens; i > 0; --i) {
|
for (size_t i = num_preopens; i > 0; --i) {
|
||||||
const preopen *pre = &preopens[i - 1];
|
const preopen *pre = &preopens[i - 1];
|
||||||
const char *prefix = pre->prefix;
|
const char *prefix = pre->prefix;
|
||||||
@ -182,6 +194,7 @@ int __wasilibc_find_abspath(const char *path,
|
|||||||
*abs_prefix = prefix;
|
*abs_prefix = prefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UNLOCK(lock);
|
||||||
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
#ifdef _REENTRANT
|
|
||||||
#error "multiple threads not supported in musl yet"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define a_barrier() (__sync_synchronize())
|
#define a_barrier() (__sync_synchronize())
|
||||||
#define a_cas(p, t, s) (__sync_val_compare_and_swap((p), (t), (s)))
|
#define a_cas(p, t, s) (__sync_val_compare_and_swap((p), (t), (s)))
|
||||||
#define a_crash() (__builtin_trap())
|
#define a_crash() (__builtin_trap())
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#ifdef _REENTRANT
|
uintptr_t __get_tp(void) {
|
||||||
#error "multiple threads not supported in musl yet"
|
#if _REENTRANT
|
||||||
|
int val;
|
||||||
|
__asm__("global.get __wasilibc_pthread_self\n"
|
||||||
|
"local.set %0"
|
||||||
|
: "=r"(val));
|
||||||
|
return val;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline struct pthread *__pthread_self(void)
|
|
||||||
{
|
|
||||||
return (struct pthread *)-1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TP_ADJ(p) (p)
|
|
||||||
|
|
||||||
#define tls_mod_off_t unsigned long long
|
|
||||||
|
@ -103,8 +103,10 @@ int pthread_setcanceltype(int, int *);
|
|||||||
void pthread_testcancel(void);
|
void pthread_testcancel(void);
|
||||||
int pthread_cancel(pthread_t);
|
int pthread_cancel(pthread_t);
|
||||||
|
|
||||||
|
#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
|
||||||
int pthread_getschedparam(pthread_t, int *__restrict, struct sched_param *__restrict);
|
int pthread_getschedparam(pthread_t, int *__restrict, struct sched_param *__restrict);
|
||||||
int pthread_setschedparam(pthread_t, int, const struct sched_param *);
|
int pthread_setschedparam(pthread_t, int, const struct sched_param *);
|
||||||
|
#endif
|
||||||
int pthread_setschedprio(pthread_t, int);
|
int pthread_setschedprio(pthread_t, int);
|
||||||
|
|
||||||
int pthread_once(pthread_once_t *, void (*)(void));
|
int pthread_once(pthread_once_t *, void (*)(void));
|
||||||
@ -167,8 +169,10 @@ int pthread_attr_getscope(const pthread_attr_t *__restrict, int *__restrict);
|
|||||||
int pthread_attr_setscope(pthread_attr_t *, int);
|
int pthread_attr_setscope(pthread_attr_t *, int);
|
||||||
int pthread_attr_getschedpolicy(const pthread_attr_t *__restrict, int *__restrict);
|
int pthread_attr_getschedpolicy(const pthread_attr_t *__restrict, int *__restrict);
|
||||||
int pthread_attr_setschedpolicy(pthread_attr_t *, int);
|
int pthread_attr_setschedpolicy(pthread_attr_t *, int);
|
||||||
|
#ifdef __wasilibc_unmodified_upstream /* WASI has no CPU scheduling support. */
|
||||||
int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict);
|
int pthread_attr_getschedparam(const pthread_attr_t *__restrict, struct sched_param *__restrict);
|
||||||
int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict);
|
int pthread_attr_setschedparam(pthread_attr_t *__restrict, const struct sched_param *__restrict);
|
||||||
|
#endif
|
||||||
int pthread_attr_getinheritsched(const pthread_attr_t *__restrict, int *__restrict);
|
int pthread_attr_getinheritsched(const pthread_attr_t *__restrict, int *__restrict);
|
||||||
int pthread_attr_setinheritsched(pthread_attr_t *, int);
|
int pthread_attr_setinheritsched(pthread_attr_t *, int);
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ long sysconf(int name)
|
|||||||
return DELAYTIMER_MAX;
|
return DELAYTIMER_MAX;
|
||||||
case JT_NPROCESSORS_CONF & 255:
|
case JT_NPROCESSORS_CONF & 255:
|
||||||
case JT_NPROCESSORS_ONLN & 255: ;
|
case JT_NPROCESSORS_ONLN & 255: ;
|
||||||
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
|
#ifdef __wasilibc_unmodified_upstream
|
||||||
unsigned char set[128] = {1};
|
unsigned char set[128] = {1};
|
||||||
int i, cnt;
|
int i, cnt;
|
||||||
__syscall(SYS_sched_getaffinity, 0, sizeof set, set);
|
__syscall(SYS_sched_getaffinity, 0, sizeof set, set);
|
||||||
@ -259,7 +259,7 @@ long sysconf(int name)
|
|||||||
for (; set[i]; set[i]&=set[i]-1, cnt++);
|
for (; set[i]; set[i]&=set[i]-1, cnt++);
|
||||||
return cnt;
|
return cnt;
|
||||||
#else
|
#else
|
||||||
// With no thread support, just say there's 1 processor.
|
// WASI has no way to query the processor count
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
#ifdef __wasilibc_unmodified_upstream // WASI has no sysinfo
|
#ifdef __wasilibc_unmodified_upstream // WASI has no sysinfo
|
||||||
|
@ -2,12 +2,18 @@
|
|||||||
#define _PTHREAD_IMPL_H
|
#define _PTHREAD_IMPL_H
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#ifdef __wasilibc_unmodified_upstream
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#ifdef __wasilibc_unmodified_upstream
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#endif
|
||||||
#include "libc.h"
|
#include "libc.h"
|
||||||
|
#ifdef __wasilibc_unmodified_upstream
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#endif
|
||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
#include "futex.h"
|
#include "futex.h"
|
||||||
|
|
||||||
@ -159,7 +165,9 @@ extern hidden volatile int __eintr_valid_flag;
|
|||||||
|
|
||||||
hidden int __clone(int (*)(void *), void *, int, void *, ...);
|
hidden int __clone(int (*)(void *), void *, int, void *, ...);
|
||||||
hidden int __set_thread_area(void *);
|
hidden int __set_thread_area(void *);
|
||||||
|
#ifdef __wasilibc_unmodified_upstream /* WASI has no sigaction */
|
||||||
hidden int __libc_sigaction(int, const struct sigaction *, struct sigaction *);
|
hidden int __libc_sigaction(int, const struct sigaction *, struct sigaction *);
|
||||||
|
#endif
|
||||||
hidden void __unmapself(void *, size_t);
|
hidden void __unmapself(void *, size_t);
|
||||||
|
|
||||||
hidden int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int);
|
hidden int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int);
|
||||||
@ -169,14 +177,22 @@ static inline void __wake(volatile void *addr, int cnt, int priv)
|
|||||||
{
|
{
|
||||||
if (priv) priv = FUTEX_PRIVATE;
|
if (priv) priv = FUTEX_PRIVATE;
|
||||||
if (cnt<0) cnt = INT_MAX;
|
if (cnt<0) cnt = INT_MAX;
|
||||||
|
#ifdef __wasilibc_unmodified_upstream
|
||||||
__syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||
|
__syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||
|
||||||
__syscall(SYS_futex, addr, FUTEX_WAKE, cnt);
|
__syscall(SYS_futex, addr, FUTEX_WAKE, cnt);
|
||||||
|
#else
|
||||||
|
__builtin_wasm_memory_atomic_notify((int*)addr, cnt);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
static inline void __futexwait(volatile void *addr, int val, int priv)
|
static inline void __futexwait(volatile void *addr, int val, int priv)
|
||||||
{
|
{
|
||||||
|
#ifdef __wasilibc_unmodified_upstream
|
||||||
if (priv) priv = FUTEX_PRIVATE;
|
if (priv) priv = FUTEX_PRIVATE;
|
||||||
__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS ||
|
__syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS ||
|
||||||
__syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
|
__syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
|
||||||
|
#else
|
||||||
|
__wait(addr, NULL, val, priv);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
hidden void __acquire_ptc(void);
|
hidden void __acquire_ptc(void);
|
||||||
|
@ -23,7 +23,7 @@ static int n = 31;
|
|||||||
static int i = 3;
|
static int i = 3;
|
||||||
static int j = 0;
|
static int j = 0;
|
||||||
static uint32_t *x = init+1;
|
static uint32_t *x = init+1;
|
||||||
#ifdef __wasilibc_unmodified_upstream
|
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
|
||||||
static volatile int lock[1];
|
static volatile int lock[1];
|
||||||
volatile int *const __random_lockptr = lock;
|
volatile int *const __random_lockptr = lock;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
#include "pthread_impl.h"
|
#include "pthread_impl.h"
|
||||||
#include <threads.h>
|
#include <threads.h>
|
||||||
|
|
||||||
|
#if !defined(__wasilibc_unmodified_upstream) && defined(__wasm__) && \
|
||||||
|
defined(_REENTRANT)
|
||||||
|
// We need some place to store the thread ID. This WebAssembly global fits the
|
||||||
|
// bill and is used by `__get_tp` elsewhere.
|
||||||
|
__asm__(".globaltype __wasilibc_pthread_self, i32\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
static pthread_t __pthread_self_internal()
|
static pthread_t __pthread_self_internal()
|
||||||
{
|
{
|
||||||
return __pthread_self();
|
return __pthread_self();
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
int __pthread_setcancelstate(int new, int *old)
|
int __pthread_setcancelstate(int new, int *old)
|
||||||
{
|
{
|
||||||
|
#if defined(__wasilibc_unmodified_upstream) || defined(_REENTRANT)
|
||||||
if (new > 2U) return EINVAL;
|
if (new > 2U) return EINVAL;
|
||||||
struct pthread *self = __pthread_self();
|
struct pthread *self = __pthread_self();
|
||||||
if (old) *old = self->canceldisable;
|
if (old) *old = self->canceldisable;
|
||||||
self->canceldisable = new;
|
self->canceldisable = new;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
#include <threads.h>
|
#include <threads.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#ifdef __wasilibc_unmodified_upstream
|
||||||
#include "syscall.h"
|
#include "syscall.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
int thrd_sleep(const struct timespec *req, struct timespec *rem)
|
int thrd_sleep(const struct timespec *req, struct timespec *rem)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user