Skip to content

Commit

Permalink
Don't use wasm global data sections when compiling with multithreadin…
Browse files Browse the repository at this point in the history
…g 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
  • Loading branch information
juj committed Dec 11, 2017
1 parent 11f4a69 commit 59a2096
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 1 deletion.
5 changes: 4 additions & 1 deletion emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1718,7 +1718,7 @@ def repl(m):
if DEBUG:
# Copy into temp dir as well, so can be run there too
shared.safe_copy(memfile, os.path.join(shared.get_emscripten_temp_dir(), os.path.basename(memfile)))
if not shared.Settings.BINARYEN or 'asmjs' in shared.Settings.BINARYEN_METHOD or 'interpret-asm2wasm' in shared.Settings.BINARYEN_METHOD:
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:
return 'memoryInitializer = "%s";' % shared.JS.get_subresource_location(memfile, embed_memfile(options))
else:
return ''
Expand Down Expand Up @@ -2310,6 +2310,9 @@ def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
if options.opt_level > 0:
cmd.append(shared.Building.opt_level_to_str(options.opt_level, options.shrink_level))
# 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)
# Note that importing (embedding) memory init file into the .wasm module as a data section is not compatible with multithreading in WebAssembly,
# because each thread would reinitialize the global data section at thread creation time, so only embed a data section to the generated
# .wasm file if not using multithreading
mem_file_exists = options.memory_init_file and os.path.exists(memfile)
import_mem_init = mem_file_exists and shared.Settings.MEM_INIT_IN_WASM
if import_mem_init:
Expand Down
6 changes: 6 additions & 0 deletions tests/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3349,6 +3349,12 @@ def test_pthread_global_data_initialization(self):
for args in [[], ['-O3']]:
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)

# Tests that spawning a new thread does not cause a reinitialization of the global data section of the application memory area.
def test_pthread_global_data_initialization(self):
for mem_init_mode in [[], ['--memory-init-file', '0'], ['--memory-init-file', '1'], ['--memory-init-file', '2']]:
for args in [[], ['-O3']]:
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'])

# test atomicrmw i64
def test_atomicrmw_i64(self):
Popen([PYTHON, EMCC, path_from_root('tests', 'atomicrmw_i64.ll'), '-s', 'USE_PTHREADS=1', '-s', 'IN_TEST_HARNESS=1', '-o', 'test.html']).communicate()
Expand Down

0 comments on commit 59a2096

Please sign in to comment.