Skip to content

Commit b25abd5

Browse files
authored
Wasm workers (emscripten-core#12833)
* Add Wasm Workers Add Wasm Workers * Add TLS test, ES6ify. * Update test * Add TLS support to Wasm Workers * Add C++11 thread_local keyword test. * Add test for C11 _Thread_local. * Add emscripten_malloc_wasm_worker and rename creation API a little. * Add documentation for Wasm Workers. * Flake and lint and fix build error * Remove deps_info dependency that does not work in current setup * __builtin_wasm_tls_align() can be zero * Add more notes about __builtin_wasm_tls_align() being zero * Add test for GCC __thread keyword. * Fix test_wasm_worker_malloc * Fix emscripten_lock_async_acquire() * Fix thread stack creation. * Fix wasm64 build * Add slack to lock_busyspin_wait_acquire * Fix typo in setting * Remove removal of TextDecoder in threads. * Fix non-Wasm Workers build * Fix file system case sensitivity * Fix Wasm Workers proxying mode generation. * Skip TLS tests on Linux, they produce an internal compiler error. * Fix typo * Fix wasm_worker.h include from C code. * Add library_wasm_worker_stub.c. * Wasm Workers working on default runtime. * flake * Disable most wasm workers tests to debug CI * Fix non-minimal runtime wasm workers startup. Add test for WASM_WORKERS=2 build mode. * Simplify in MINIMAL_RUNTIME preamble assignment for wasm maximum memory. * Fix USE_PTHREADS+WASM_WORKERS line. * Add support for simultaneous pthreads + Wasm workers. * Do not pass redundant TLS size to Wasm Worker creation side. * Update emcc.py wasm worker deps * Remove special handling of .S files in system_libs build * Update documentation * Add code size test. * flake * Update tests and wasm worker MT build * Fix mt build * Adjust mt build * Update code size test * Update hello worker wasm * flake * Address review: Allow building with -sSHARED_MEMORY and add a test. Move code from emcc.py to library_wasm_worker.js. * Remove unnecessary dynCall statements * Update mention of C11 and C++11 Atomics APIs * Remove old code. * Utilize runOnMainThread() in MINIMAL_RUNTIME ready handler. * Simplify code * #error quotes * Clean typo * Cleanup tests * Update ChangeLog * Fixes * Add test files. * Fix pthreads * Remove moved test * Address review * Small code size optimization * Small code size opt * Flake * Update Wasm Workers code size test
1 parent a18bbf7 commit b25abd5

File tree

68 files changed

+3804
-36
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+3804
-36
lines changed

.eslintrc.yml

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ ignorePatterns:
2121
- "src/embind/"
2222
- "src/emrun_postjs.js"
2323
- "src/worker.js"
24+
- "src/wasm_worker.js"
2425
- "src/wasm2js.js"
2526
- "src/webGLClient.js"
2627
- "src/webGLWorker.js"

ChangeLog.md

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ See docs/process.md for more on how version tagging works.
2626
- Fix deadlock in `munmap` that was introduced in 3.1.5. The deadlock would
2727
occur in multi-threaded programs when a partial unmap was requested (which
2828
emscripten does not support). (#16413)
29+
- Added new compiler+linker option -sSHARED_MEMORY=1, which enables targeting
30+
a shared WebAssembly.Memory. (#16419)
31+
- Added new API "Wasm Workers", which is an alternative to pthreads for building
32+
multithreaded applications, enabled via -sWASM_WORKERS=1 (#12833)
2933

3034
3.1.6 - 02/24/2022
3135
------------------

emcc.py

+35-3
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,9 @@ def get_cflags(user_args):
833833
if settings.SHARED_MEMORY:
834834
cflags.append('-D__EMSCRIPTEN_SHARED_MEMORY__=1')
835835

836+
if settings.WASM_WORKERS:
837+
cflags.append('-D__EMSCRIPTEN_WASM_WORKERS__=1')
838+
836839
if not settings.STRICT:
837840
# The preprocessor define EMSCRIPTEN is deprecated. Don't pass it to code
838841
# in strict mode. Code should use the define __EMSCRIPTEN__ instead.
@@ -1424,11 +1427,17 @@ def phase_setup(options, state, newargs, user_settings):
14241427
if settings.MAIN_MODULE or settings.SIDE_MODULE:
14251428
settings.RELOCATABLE = 1
14261429

1427-
if settings.USE_PTHREADS:
1430+
# Pthreads and Wasm Workers require targeting shared Wasm memory (SAB).
1431+
if settings.USE_PTHREADS or settings.WASM_WORKERS:
14281432
settings.SHARED_MEMORY = 1
14291433

1430-
if settings.SHARED_MEMORY and '-pthread' not in newargs:
1434+
if settings.USE_PTHREADS and '-pthread' not in newargs:
14311435
newargs += ['-pthread']
1436+
elif settings.SHARED_MEMORY:
1437+
if '-matomics' not in newargs:
1438+
newargs += ['-matomics']
1439+
if '-mbulk-memory' not in newargs:
1440+
newargs += ['-mbulk-memory']
14321441

14331442
if 'DISABLE_EXCEPTION_CATCHING' in user_settings and 'EXCEPTION_CATCHING_ALLOWED' in user_settings:
14341443
# If we get here then the user specified both DISABLE_EXCEPTION_CATCHING and EXCEPTION_CATCHING_ALLOWED
@@ -2064,6 +2073,18 @@ def phase_linker_setup(options, state, newargs, user_settings):
20642073
if settings.INCLUDE_FULL_LIBRARY and not settings.DISABLE_EXCEPTION_CATCHING:
20652074
settings.EXPORTED_FUNCTIONS += ['_emscripten_format_exception', '_free']
20662075

2076+
if settings.WASM_WORKERS:
2077+
# TODO: After #15982 is resolved, these dependencies can be declared in library_wasm_worker.js
2078+
# instead of having to record them here.
2079+
wasm_worker_imports = ['_emscripten_wasm_worker_initialize']
2080+
settings.EXPORTED_FUNCTIONS += wasm_worker_imports
2081+
building.user_requested_exports.update(wasm_worker_imports)
2082+
settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['_wasm_worker_initializeRuntime']
2083+
# set location of Wasm Worker bootstrap JS file
2084+
if settings.WASM_WORKERS == 1:
2085+
settings.WASM_WORKER_FILE = unsuffixed(os.path.basename(target)) + '.ww.js'
2086+
settings.JS_LIBRARIES.append((0, shared.path_from_root('src', 'library_wasm_worker.js')))
2087+
20672088
if settings.FORCE_FILESYSTEM and not settings.MINIMAL_RUNTIME:
20682089
# when the filesystem is forced, we export by default methods that filesystem usage
20692090
# may need, including filesystem usage from standalone file packager output (i.e.
@@ -2803,8 +2824,8 @@ def phase_final_emitting(options, state, target, wasm_target, memfile):
28032824
# src = re.sub(r'\n+[ \n]*\n+', '\n', src)
28042825
# write_file(final_js, src)
28052826

2827+
target_dir = os.path.dirname(os.path.abspath(target))
28062828
if settings.USE_PTHREADS:
2807-
target_dir = os.path.dirname(os.path.abspath(target))
28082829
worker_output = os.path.join(target_dir, settings.PTHREAD_WORKER_FILE)
28092830
contents = shared.read_and_preprocess(utils.path_from_root('src/worker.js'), expand_macros=True)
28102831
write_file(worker_output, contents)
@@ -2814,6 +2835,17 @@ def phase_final_emitting(options, state, target, wasm_target, memfile):
28142835
minified_worker = building.acorn_optimizer(worker_output, ['minifyWhitespace'], return_output=True)
28152836
write_file(worker_output, minified_worker)
28162837

2838+
# Deploy the Wasm Worker bootstrap file as an output file (*.ww.js)
2839+
if settings.WASM_WORKERS == 1:
2840+
worker_output = os.path.join(target_dir, settings.WASM_WORKER_FILE)
2841+
with open(worker_output, 'w') as f:
2842+
f.write(shared.read_and_preprocess(shared.path_from_root('src', 'wasm_worker.js'), expand_macros=True))
2843+
2844+
# Minify the wasm_worker.js file in optimized builds
2845+
if (settings.OPT_LEVEL >= 1 or settings.SHRINK_LEVEL >= 1) and not settings.DEBUG_LEVEL:
2846+
minified_worker = building.acorn_optimizer(worker_output, ['minifyWhitespace'], return_output=True)
2847+
open(worker_output, 'w').write(minified_worker)
2848+
28172849
# track files that will need native eols
28182850
generated_text_files_with_native_eols = []
28192851

site/source/_themes/emscripten_sphinx_rtd_theme/static/css/theme.css

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/source/docs/api_reference/index.rst

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ This section lists Emscripten's public API, organised by header file. At a very
2121
- :ref:`Fetch-API`:
2222
API for managing accesses to network XHR and IndexedDB.
2323

24+
- :ref:`wasm_workers`:
25+
Enables writing multithreaded programs using a web-like API.
26+
2427
- :ref:`Module`:
2528
Global JavaScript object that can be used to control code execution and access exported methods.
2629

@@ -53,6 +56,7 @@ This section lists Emscripten's public API, organised by header file. At a very
5356
bind.h
5457
trace.h
5558
fiber.h
59+
wasm_workers
5660
advanced-apis
5761

5862

0 commit comments

Comments
 (0)