Skip to content

Commit 59a2096

Browse files
committed
Don't use wasm global data sections when compiling with multithreading enabled so that pthread_create() will not reset the global data members. Instead use a separate .mem file or base64-embedded data in JS file for memory initialization. See WebAssembly/threads#62
1 parent 11f4a69 commit 59a2096

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

emcc.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1718,7 +1718,7 @@ def repl(m):
17181718
if DEBUG:
17191719
# Copy into temp dir as well, so can be run there too
17201720
shared.safe_copy(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
1721-
if not shared.Settings.BINARYEN or 'asmjs' in shared.Settings.BINARYEN_METHOD or 'interpret-asm2wasm' in shared.Settings.BINARYEN_METHOD:
1721+
if not shared.Settings.BINARYEN or 'asmjs' in shared.Settings.BINARYEN_METHOD or 'interpret-asm2wasm' in shared.Settings.BINARYEN_METHOD or shared.Settings.USE_PTHREADS:
17221722
return 'memoryInitializer = "%s";' % shared.JS.get_subresource_location(memfile, embed_memfile(options))
17231723
else:
17241724
return ''
@@ -2310,6 +2310,9 @@ def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
23102310
if options.opt_level > 0:
23112311
cmd.append(shared.Building.opt_level_to_str(options.opt_level, options.shrink_level))
23122312
# import mem init file if it exists, and if we will not be using asm.js as a binaryen method (as it needs the mem init file, of course)
2313+
# Note that importing (embedding) memory init file into the .wasm module as a data section is not compatible with multithreading in WebAssembly,
2314+
# because each thread would reinitialize the global data section at thread creation time, so only embed a data section to the generated
2315+
# .wasm file if not using multithreading
23132316
mem_file_exists = options.memory_init_file and os.path.exists(memfile)
23142317
import_mem_init = mem_file_exists and shared.Settings.MEM_INIT_IN_WASM
23152318
if import_mem_init:

tests/test_browser.py

+6
Original file line numberDiff line numberDiff line change
@@ -3349,6 +3349,12 @@ def test_pthread_global_data_initialization(self):
33493349
for args in [[], ['-O3']]:
33503350
self.btest(path_from_root('tests', 'pthread', 'test_pthread_global_data_initialization.c'), expected='20', args=args+mem_init_mode+['-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1'], also_wasm=False)
33513351

3352+
# Tests that spawning a new thread does not cause a reinitialization of the global data section of the application memory area.
3353+
def test_pthread_global_data_initialization(self):
3354+
for mem_init_mode in [[], ['--memory-init-file', '0'], ['--memory-init-file', '1'], ['--memory-init-file', '2']]:
3355+
for args in [[], ['-O3']]:
3356+
self.btest_wasm(path_from_root('tests', 'pthread', 'test_pthread_global_data_initialization.c'), expected='20', args=args+mem_init_mode+['-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1'])
3357+
33523358
# test atomicrmw i64
33533359
def test_atomicrmw_i64(self):
33543360
Popen([PYTHON, EMCC, path_from_root('tests', 'atomicrmw_i64.ll'), '-s', 'USE_PTHREADS=1', '-s', 'IN_TEST_HARNESS=1', '-o', 'test.html']).communicate()

0 commit comments

Comments
 (0)