Skip to content

Commit 60de330

Browse files
authored
Move thread exit code to native. NFC (#14853)
1 parent 7e538a4 commit 60de330

7 files changed

+54
-45
lines changed

emcc.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1864,7 +1864,6 @@ def default_setting(name, new_default):
18641864
settings.JS_LIBRARIES.append((0, 'library_pthread.js'))
18651865
settings.EXPORTED_FUNCTIONS += [
18661866
'___emscripten_pthread_data_constructor',
1867-
'___pthread_tsd_run_dtors',
18681867
'__emscripten_call_on_thread',
18691868
'__emscripten_main_thread_futex',
18701869
'__emscripten_thread_init',

src/library_pthread.js

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -128,18 +128,6 @@ var LibraryPThread = {
128128
},
129129
#endif
130130

131-
runExitHandlers: function() {
132-
while (PThread.threadExitHandlers.length > 0) {
133-
PThread.threadExitHandlers.pop()();
134-
}
135-
136-
// Call into the musl function that runs destructors of all thread-specific data.
137-
#if ASSERTIONS
138-
assert(_pthread_self())
139-
#endif
140-
___pthread_tsd_run_dtors();
141-
},
142-
143131
setExitStatus: function(status) {
144132
EXITSTATUS = status;
145133
},
@@ -949,39 +937,26 @@ var LibraryPThread = {
949937
return wasDetached ? {{{ cDefine('EINVAL') }}} : 0;
950938
},
951939

952-
__pthread_exit_js__deps: ['exit'],
953-
__pthread_exit_js: function(status) {
954-
// Called when we are performing a pthread_exit(), either explicitly called
940+
__pthread_exit_run_handlers__deps: ['exit'],
941+
__pthread_exit_run_handlers: function(status) {
942+
// Called from pthread_exit, either when called explicitly called
955943
// by programmer, or implicitly when leaving the thread main function.
956-
if (!ENVIRONMENT_IS_PTHREAD) {
957-
PThread.runExitHandlers();
958-
_exit(status);
959-
// unreachable
960-
961-
}
962944

963-
var tb = _pthread_self();
964945
#if PTHREADS_DEBUG
946+
var tb = _pthread_self();
965947
assert(tb);
966948
out('Pthread 0x' + tb.toString(16) + ' exited.');
967949
#endif
968950

969-
// Disable all cancellation so that executing the cleanup handlers won't trigger another JS
970-
// canceled exception to be thrown.
971-
Atomics.store(HEAPU32, (tb + {{{ C_STRUCTS.pthread.canceldisable }}} ) >> 2, 1/*PTHREAD_CANCEL_DISABLE*/);
972-
Atomics.store(HEAPU32, (tb + {{{ C_STRUCTS.pthread.cancelasync }}} ) >> 2, 0/*PTHREAD_CANCEL_DEFERRED*/);
973-
PThread.runExitHandlers();
974-
975-
Atomics.store(HEAPU32, (tb + {{{ C_STRUCTS.pthread.result }}} ) >> 2, status);
976-
// When we publish this, the main thread is free to deallocate the thread object and we are done.
977-
// Therefore set _pthread_self = 0; above to 'release' the object in this worker thread.
978-
Atomics.store(HEAPU32, (tb + {{{ C_STRUCTS.pthread.threadStatus }}} ) >> 2, 1); // Mark the thread as no longer running.
979-
980-
_emscripten_futex_wake(tb + {{{ C_STRUCTS.pthread.threadStatus }}}, {{{ cDefine('INT_MAX') }}}); // wake all threads
981-
982-
// Not hosting a pthread anymore in this worker, reset the info structures to null.
983-
__emscripten_thread_init(0, 0, 0); // Unregister the thread block inside the wasm module.
951+
while (PThread.threadExitHandlers.length > 0) {
952+
PThread.threadExitHandlers.pop()();
953+
}
954+
},
984955

956+
__pthread_exit_done: function() {
957+
// Called at the end of pthread_exit, either when called explicitly called
958+
// by programmer, or implicitly when leaving the thread main function.
959+
//
985960
// Note: in theory we would like to return any offscreen canvases back to the main thread,
986961
// but if we ever fetched a rendering context for them that would not be valid, so we don't try.
987962
postMessage({ 'cmd': 'exit' });

system/lib/pthread/pthread_create.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,16 @@
1616

1717
extern int __cxa_thread_atexit(void (*)(void *), void *, void *);
1818
extern int __pthread_create_js(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
19-
extern void __pthread_exit_js(void* status);
19+
extern void _emscripten_thread_init(int, int, int);
20+
extern void __pthread_exit_run_handlers();
21+
extern void __pthread_exit_done();
2022
extern int8_t __dso_handle;
2123

24+
static void dummy_0()
25+
{
26+
}
27+
weak_alias(dummy_0, __pthread_tsd_run_dtors);
28+
2229
void __run_cleanup_handlers(void* _unused) {
2330
pthread_t self = __pthread_self();
2431
while (self->cancelbuf) {
@@ -48,9 +55,35 @@ int __pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*star
4855
return __pthread_create_js(thread, attr, start_routine, arg);
4956
}
5057

51-
void _emscripten_thread_exit(void* retval) {
52-
assert(pthread_self());
53-
__pthread_exit_js(retval);
58+
void _emscripten_thread_exit(void* result) {
59+
struct pthread *self = __pthread_self();
60+
assert(self);
61+
62+
self->canceldisable = PTHREAD_CANCEL_DISABLE;
63+
self->cancelasync = PTHREAD_CANCEL_DEFERRED;
64+
self->result = result;
65+
66+
__pthread_exit_run_handlers();
67+
68+
// Call into the musl function that runs destructors of all thread-specific data.
69+
__pthread_tsd_run_dtors();
70+
71+
if (self == emscripten_main_browser_thread_id()) {
72+
// FIXME(sbc): When pthread_exit causes the entire application to exit
73+
// we should be returning zero (according to the man page for pthread_exit).
74+
exit((intptr_t)result);
75+
return;
76+
}
77+
78+
// Mark the thread as no longer running.
79+
// When we publish this, the main thread is free to deallocate the thread object and we are done.
80+
self->threadStatus = 1;
81+
82+
emscripten_futex_wake(&self->threadStatus, INT_MAX); // wake all threads
83+
84+
// Not hosting a pthread anymore in this worker, reset the info structures to null.
85+
_emscripten_thread_init(0, 0, 0); // Unregister the thread block inside the wasm module.
86+
__pthread_exit_done();
5487
}
5588

5689
// Mark as `no_sanitize("address"` since emscripten_pthread_exit destroys

tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.exports

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ M
1414
N
1515
O
1616
P
17-
t
18-
u
17+
Q
1918
v
2019
w
2120
x

tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.funcs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ $__pthread_mutex_trylock
77
$__pthread_mutex_unlock
88
$__pthread_self_internal
99
$__pthread_setcancelstate
10-
$__pthread_tsd_run_dtors
1110
$__wasm_call_ctors
1211
$__wasm_init_memory
1312
$_do_call

tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.imports

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ a.p
1717
a.q
1818
a.r
1919
a.s
20+
a.t
21+
a.u

tests/other/metadce/minimal_main_Oz_USE_PTHREADS_PROXY_TO_PTHREAD.sent

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ p
1717
q
1818
r
1919
s
20+
t
21+
u

0 commit comments

Comments
 (0)