emscripten-core / emscripten-core/emscripten

Standard library libc code cannot unconditionally use atomics / tls because of `-sSHARED_MEMORY` setting

Open
#20,803 8 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.