emscripten-core / emscripten-core/emscripten
Standard library libc code cannot unconditionally use atomics / tls because of `-sSHARED_MEMORY` setting
- Dominant language
- C++
- Stars
- 27.6k
- Forks
- 3.6k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 105
Description
We have a setting called `-sSHARED_MEMORY` which can be used in programs that don't use either pthreads or wasm workers. In this case we link against the non-threaded version libc and expect all atomic and TLS operations to be lowered away.
My understanding is that this mode is designed user who want to share memory with worker but don't expect to be able use any C/C++ synchronization primitives and instead do all their synchronization in JS.
See https://groups.google.com/g/emscripten-discuss/c/IsRC-MRGQjw for example.
The way this setting is implemented means we cannot currently use `_Atomic` in libc code. For example attempting to use `_Atomic` in sbrk yeilds the following error in tests that use `-sSHARED_MEMORY`:
```
$ test/runner other.test_shared_memory_minimal_runtime --skip-slow
Test suites:
['test_other']
Running test_other: (1 tests)
(checking sanity from test runner)
shared:INFO: (Emscripten: Running sanity checks)
test_shared_memory_minimal_runtime (test_other.other.test_shared_memory_minimal_runtime) ... Clearing existing test directory
wasm-ld: error: --shared-memory is disallowed by sbrk.o because it was not compiled with 'atomics' or 'bulk-memory' features.
emcc: error: '/usr/local/google/home/sbc/dev/wasm/llvm-build/bin/wasm-ld -o shared_memory.wasm /tmp/emscripten_temp_j6d0bcpl/shared_memory_0.o -L/usr/local/google/home/sbc/dev/wasm/emscripten/cache/sysroot/lib/wasm32-emscripten /usr/local/google/home/sbc/dev/wasm/emscripten/cache/sysroot/lib/wasm32-emscripten/crtbegin.o -lGL -lal -lhtml5 -lbulkmemory -lstubs-debug -lnoexit -lc-debug -ldlmalloc-noerrno -lcompiler_rt -lsockets -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr /tmp/tmp26_xe79ylibemscripten_js_symbols.so --import-memory --shared-memory --strip-debug --export-if-defined=main --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=__main_argc_argv --export-if-defined=fflush --export=emscripten_stack_get_end --export=emscripten_stack_get_free --export=emscripten_stack_get_base --export=emscripten_stack_get_current --export=emscripten_stack_init --export=stackSave --export=stackRestore --export=stackAlloc --export=__get_temp_ret --export=__set_temp_ret --export=__wasm_call_ctors --export-table -z stack-size=65536 --initial-memory=16777216 --max-memory=16777216 --no-entry --stack-first --table-base=1' failed (returned 1)
```
See #20793.
Possible solutions:
1. Link against libc-mt when building with `-sSHARED_MEMORY`
2. Tell the linker to ignore "not compiled with 'atomics' or 'bulk-memory' features." errors when linking with `-sSHARED_MEMORY`
3. Remove `-sSHARED_MEMORY` as a user-facing flag and ask users to use either pthreads or wasm workers if they want shared memory.
Contributor guide
Assessment
This issue has not been assessed yet.