Skip to content

gh-84461: Add --enable-wasm-pthreads and more file systems (GH-91820) #91820

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Doc/using/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ WebAssemby Options

.. versionadded:: 3.11

.. cmdoption:: --enable-wasm-pthreads

Turn on pthreads support for WASM.

.. versionadded:: 3.11


Install Options
---------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add :option:`--enable-wasm-pthreads` to enable pthreads support for WASM
builds. ``Emscripten/node`` no longer has threading enabled by default.
Include additional file systems.
25 changes: 15 additions & 10 deletions Tools/wasm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,27 @@ functions.
- The ``select`` module is limited. ``select.select()`` crashes the runtime
due to lack of exectfd support.

## processes, threads, signals
## processes, signals

- Processes are not supported. System calls like fork, popen, and subprocess
fail with ``ENOSYS`` or ``ENOSUP``.
- Signal support is limited. ``signal.alarm``, ``itimer``, ``sigaction``
are not available or do not work correctly. ``SIGTERM`` exits the runtime.
- Keyboard interrupt (CTRL+C) handling is not implemented yet.
- Browser builds cannot start new threads. Node's web workers consume
extra file descriptors.
- Resource-related functions like ``os.nice`` and most functions of the
``resource`` module are not available.

## threading

- Threading is disabled by default. The ``configure`` option
``--enable-wasm-pthreads`` adds compiler flag ``-pthread`` and
linker flags ``-sUSE_PTHREADS -sPROXY_TO_PTHREAD``.
- pthread support requires WASM threads and SharedArrayBuffer (bulk memory).
The Node.JS runtime keeps a pool of web workers around. Each web worker
uses several file descriptors (eventfd, epoll, pipe).
- It's not advised to enable threading when building for browsers or with
dynamic linking support; there are performance and stability issues.

## file system

- Most user, group, and permission related function and modules are not
Expand Down Expand Up @@ -173,20 +182,16 @@ functions.
distutils, multiprocessing, dbm, tests and similar modules
are not shipped. All other modules are bundled as pre-compiled
``pyc`` files.
- Threading is disabled.
- In-memory file system (MEMFS) is not persistent and limited.
- Test modules are disabled by default. Use ``--enable-test-modules`` build
test modules like ``_testcapi``.

## wasm32-emscripten in node

Node builds use ``NODERAWFS``, ``USE_PTHREADS`` and ``PROXY_TO_PTHREAD``
linker options.
Node builds use ``NODERAWFS``.

- Node RawFS allows direct access to the host file system.
- pthread support requires WASM threads and SharedArrayBuffer (bulk memory).
The runtime keeps a pool of web workers around. Each web worker uses
several file descriptors (eventfd, epoll, pipe).
- Node RawFS allows direct access to the host file system without need to
perform ``FS.mount()`` call.

# Hosting Python WASM builds

Expand Down
106 changes: 80 additions & 26 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 57 additions & 27 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,21 @@ AC_ARG_ENABLE([wasm-dynamic-linking],
])
AC_MSG_RESULT([$enable_wasm_dynamic_linking])

AC_MSG_CHECKING([for --enable-wasm-pthreads])
AC_ARG_ENABLE([wasm-pthreads],
[AS_HELP_STRING([--enable-wasm-pthreads],
[Enable pthread emulation for WebAssembly (default is no)])],
[
AS_CASE([$ac_sys_system],
[Emscripten], [],
[WASI], [AC_MSG_ERROR([WASI threading is not implemented yet.])],
[AC_MSG_ERROR([--enable-wasm-pthreads only applies to Emscripten and WASI])]
)
], [
enable_wasm_pthreads=missing
])
AC_MSG_RESULT([$enable_wasm_pthreads])

AC_MSG_CHECKING([for --with-suffix])
AC_ARG_WITH([suffix],
[AS_HELP_STRING([--with-suffix=SUFFIX], [set executable suffix to SUFFIX (default is empty, yes is mapped to '.exe')])],
Expand Down Expand Up @@ -1909,38 +1924,53 @@ then
fi

# WASM flags
AS_CASE([$ac_sys_system/$ac_sys_emscripten_target],
[Emscripten/browser*], [
LDFLAGS_NODIST="$LDFLAGS_NODIST -sALLOW_MEMORY_GROWTH"
LINKFORSHARED="--preload-file=\$(WASM_ASSETS_DIR)"
AS_CASE([$ac_sys_system],
[Emscripten], [
dnl build with WASM debug info if either Py_DEBUG is set or the target is
dnl node-debug or browser-debug.
AS_VAR_IF([Py_DEBUG], [yes], [wasm_debug=yes], [wasm_debug=no])

dnl Start with 20 MB and allow to grow
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sALLOW_MEMORY_GROWTH -sTOTAL_MEMORY=20971520"])

dnl Include file system support
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js"])

AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [
AS_VAR_APPEND([LINKFORSHARED], [" -sMAIN_MODULE"])
])
WASM_ASSETS_DIR=".\$(prefix)"
WASM_STDLIB="\$(WASM_ASSETS_DIR)/local/lib/python\$(VERSION)/os.py"
dnl separate-dwarf does not seem to work in Chrome DevTools Support.
if test "$Py_DEBUG" = 'true' -o "$ac_sys_emscripten_target" = "browser-debug"; then
LDFLAGS_NODIST="$LDFLAGS_NODIST -sASSERTIONS"
LINKFORSHARED="$LINKFORSHARED -gsource-map --emit-symbol-map"
else
LINKFORSHARED="$LINKFORSHARED -O2 -g0"
fi
],
[Emscripten/node*], [
LDFLAGS_NODIST="$LDFLAGS_NODIST -sALLOW_MEMORY_GROWTH -sNODERAWFS -sUSE_PTHREADS"
LINKFORSHARED="-sPROXY_TO_PTHREAD -sEXIT_RUNTIME"
AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [
AS_VAR_APPEND([LINKFORSHARED], [" -sMAIN_MODULE"])

AS_VAR_IF([enable_wasm_pthreads], [yes], [
AS_VAR_APPEND([CFLAGS_NODIST], [" -pthread"])
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sUSE_PTHREADS"])
AS_VAR_APPEND([LINKFORSHARED], [" -sPROXY_TO_PTHREAD"])
])

AS_CASE([$ac_sys_emscripten_target],
[browser*], [
AS_VAR_IF([ac_sys_emscripten_target], [browser-debug], [wasm_debug=yes])
AS_VAR_APPEND([LINKFORSHARED], [" --preload-file=\$(WASM_ASSETS_DIR)"])
WASM_ASSETS_DIR=".\$(prefix)"
WASM_STDLIB="\$(WASM_ASSETS_DIR)/local/lib/python\$(VERSION)/os.py"
dnl separate-dwarf does not seem to work in Chrome DevTools Support.
WASM_LINKFORSHARED_DEBUG="-gsource-map --emit-symbol-map"
],
[node*], [
AS_VAR_IF([ac_sys_emscripten_target], [node-debug], [wasm_debug=yes])
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sALLOW_MEMORY_GROWTH -sNODERAWFS"])
AS_VAR_APPEND([LINKFORSHARED], [" -sEXIT_RUNTIME"])
WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map"
]
)

AS_VAR_IF([wasm_debug], [yes], [
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sASSERTIONS"])
AS_VAR_APPEND([LINKFORSHARED], [" $WASM_LINKFORSHARED_DEBUG"])
], [
AS_VAR_APPEND([LINKFORSHARED], [" -O2 -g0"])
])
CFLAGS_NODIST="$CFLAGS_NODIST -pthread"
if test "$Py_DEBUG" = 'true' -o "$ac_sys_emscripten_target" = "node-debug"; then
LDFLAGS_NODIST="$LDFLAGS_NODIST -sASSERTIONS"
LINKFORSHARED="$LINKFORSHARED -gseparate-dwarf --emit-symbol-map"
else
LINKFORSHARED="$LINKFORSHARED -O2 -g0"
fi
],
[WASI/*], [
[WASI], [
AC_DEFINE([_WASI_EMULATED_SIGNAL], [1], [Define to 1 if you want to emulate signals on WASI])
AC_DEFINE([_WASI_EMULATED_GETPID], [1], [Define to 1 if you want to emulate getpid() on WASI])
AC_DEFINE([_WASI_EMULATED_PROCESS_CLOCKS], [1], [Define to 1 if you want to emulate process clocks on WASI])
Expand Down