Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions system/lib/libcxx/include/__locale
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ private:
};

class _LIBCPP_EXPORTED_FROM_ABI locale::id {
#if !defined(__EMSCRIPTEN__) || !defined(__EMSCRIPTEN_WASM_WORKERS__)
once_flag __flag_;
#endif
int32_t __id_;

static int32_t __next_id;
Expand Down
17 changes: 17 additions & 0 deletions system/lib/libcxx/src/locale.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,24 @@ void locale::facet::__on_zero_shared() noexcept { delete this; }
constinit int32_t locale::id::__next_id = 0;

long locale::id::__get() {
#if defined(__EMSCRIPTEN__) && defined(__EMSCRIPTEN_WASM_WORKERS__)
// Avoid `call_once` under Emscripten since we want to avoid the pthread
// dependenency that it comes with.
// TODO(https://github.com/emscripten-core/emscripten/issues/26426):
// Remove this patch once we have some kind of locking primitive
// in Wasm Worker that can be used to implement call_once (or
// __libcpp_mutex_t/__libcpp_condvar_t).
if (__libcpp_atomic_load(&__id_) == 0) {
int32_t proposed_id = __libcpp_atomic_add(&__next_id, 1);
int32_t expected = 0;
// If we race with another thread here the CAS will fail and
// the proposed_id will be leaked, but __id_ will be non-zero
// in either case.
__libcpp_atomic_compare_exchange(&__id_, &expected, proposed_id);
}
#else
call_once(__flag_, [&] { __id_ = __libcpp_atomic_add(&__next_id, 1); });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we leave this file unchanged but reimplement call_once using the new code above?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, I considered something like that. But to implement call_once correctly I think we would really need something like a mutex+condvar, at least that is currently how libc++ implements call_once (using __libcpp_mutex_t + __libcpp_condvar_t).

This little construct is less complex/powerful than mutex+condvar I think.

That is what the TODO here is for.

I maybe have through Gemini at this and have it try to implement that for us .. at least I'll open a bug now.

#endif
return __id_ - 1;
}

Expand Down
1 change: 0 additions & 1 deletion test/codesize/hello_libcxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ int main() {
std::cout << "hello, world!" << std::endl;
return 0;
}

3 changes: 3 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -13537,6 +13537,9 @@ def test_wasm_worker_pthread_api_usage(self):
def test_wasm_worker_cxx_init(self):
self.do_run_in_out_file_test('wasm_worker/wasm_worker_cxx_init.cpp', cflags=['-sWASM_WORKERS'])

def test_wasm_worker_hello_libcxx(self):
self.do_runf('codesize/hello_libcxx.cpp', 'hello, world!\n', cflags=['-sWASM_WORKERS'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.do_runf('codesize/hello_libcxx.cpp', 'hello, world!\n', cflags=['-sWASM_WORKERS'])
self.do_runf('hello_libcxx.cpp', 'hello, world!\n', cflags=['-sWASM_WORKERS'])

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this isn't a code size test


@parameterized({
# we will warn here since -O2 runs the optimizer and -g enables DWARF
'O2_g': (True, ['-O2', '-g']),
Expand Down