Move thread exit code to native. NFC (#14853)
This commit is contained in:
Родитель
7e538a419c
Коммит
60de3300c4
1
emcc.py
1
emcc.py
|
@ -1864,7 +1864,6 @@ def phase_linker_setup(options, state, newargs, settings_map):
|
|||
settings.JS_LIBRARIES.append((0, 'library_pthread.js'))
|
||||
settings.EXPORTED_FUNCTIONS += [
|
||||
'___emscripten_pthread_data_constructor',
|
||||
'___pthread_tsd_run_dtors',
|
||||
'__emscripten_call_on_thread',
|
||||
'__emscripten_main_thread_futex',
|
||||
'__emscripten_thread_init',
|
||||
|
|
|
@ -128,18 +128,6 @@ var LibraryPThread = {
|
|||
},
|
||||
#endif
|
||||
|
||||
runExitHandlers: function() {
|
||||
while (PThread.threadExitHandlers.length > 0) {
|
||||
PThread.threadExitHandlers.pop()();
|
||||
}
|
||||
|
||||
// Call into the musl function that runs destructors of all thread-specific data.
|
||||
#if ASSERTIONS
|
||||
assert(_pthread_self())
|
||||
#endif
|
||||
___pthread_tsd_run_dtors();
|
||||
},
|
||||
|
||||
setExitStatus: function(status) {
|
||||
EXITSTATUS = status;
|
||||
},
|
||||
|
@ -949,39 +937,26 @@ var LibraryPThread = {
|
|||
return wasDetached ? {{{ cDefine('EINVAL') }}} : 0;
|
||||
},
|
||||
|
||||
__pthread_exit_js__deps: ['exit'],
|
||||
__pthread_exit_js: function(status) {
|
||||
// Called when we are performing a pthread_exit(), either explicitly called
|
||||
__pthread_exit_run_handlers__deps: ['exit'],
|
||||
__pthread_exit_run_handlers: function(status) {
|
||||
// Called from pthread_exit, either when called explicitly called
|
||||
// by programmer, or implicitly when leaving the thread main function.
|
||||
if (!ENVIRONMENT_IS_PTHREAD) {
|
||||
PThread.runExitHandlers();
|
||||
_exit(status);
|
||||
// unreachable
|
||||
|
||||
}
|
||||
|
||||
var tb = _pthread_self();
|
||||
#if PTHREADS_DEBUG
|
||||
var tb = _pthread_self();
|
||||
assert(tb);
|
||||
out('Pthread 0x' + tb.toString(16) + ' exited.');
|
||||
#endif
|
||||
|
||||
// Disable all cancellation so that executing the cleanup handlers won't trigger another JS
|
||||
// canceled exception to be thrown.
|
||||
Atomics.store(HEAPU32, (tb + {{{ C_STRUCTS.pthread.canceldisable }}} ) >> 2, 1/*PTHREAD_CANCEL_DISABLE*/);
|
||||
Atomics.store(HEAPU32, (tb + {{{ C_STRUCTS.pthread.cancelasync }}} ) >> 2, 0/*PTHREAD_CANCEL_DEFERRED*/);
|
||||
PThread.runExitHandlers();
|
||||
|
||||
Atomics.store(HEAPU32, (tb + {{{ C_STRUCTS.pthread.result }}} ) >> 2, status);
|
||||
// When we publish this, the main thread is free to deallocate the thread object and we are done.
|
||||
// Therefore set _pthread_self = 0; above to 'release' the object in this worker thread.
|
||||
Atomics.store(HEAPU32, (tb + {{{ C_STRUCTS.pthread.threadStatus }}} ) >> 2, 1); // Mark the thread as no longer running.
|
||||
|
||||
_emscripten_futex_wake(tb + {{{ C_STRUCTS.pthread.threadStatus }}}, {{{ cDefine('INT_MAX') }}}); // wake all threads
|
||||
|
||||
// Not hosting a pthread anymore in this worker, reset the info structures to null.
|
||||
__emscripten_thread_init(0, 0, 0); // Unregister the thread block inside the wasm module.
|
||||
while (PThread.threadExitHandlers.length > 0) {
|
||||
PThread.threadExitHandlers.pop()();
|
||||
}
|
||||
},
|
||||
|
||||
__pthread_exit_done: function() {
|
||||
// Called at the end of pthread_exit, either when called explicitly called
|
||||
// by programmer, or implicitly when leaving the thread main function.
|
||||
//
|
||||
// Note: in theory we would like to return any offscreen canvases back to the main thread,
|
||||
// but if we ever fetched a rendering context for them that would not be valid, so we don't try.
|
||||
postMessage({ 'cmd': 'exit' });
|
||||
|
|
|
@ -16,9 +16,16 @@
|
|||
|
||||
extern int __cxa_thread_atexit(void (*)(void *), void *, void *);
|
||||
extern int __pthread_create_js(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
|
||||
extern void __pthread_exit_js(void* status);
|
||||
extern void _emscripten_thread_init(int, int, int);
|
||||
extern void __pthread_exit_run_handlers();
|
||||
extern void __pthread_exit_done();
|
||||
extern int8_t __dso_handle;
|
||||
|
||||
static void dummy_0()
|
||||
{
|
||||
}
|
||||
weak_alias(dummy_0, __pthread_tsd_run_dtors);
|
||||
|
||||
void __run_cleanup_handlers(void* _unused) {
|
||||
pthread_t self = __pthread_self();
|
||||
while (self->cancelbuf) {
|
||||
|
@ -48,9 +55,35 @@ int __pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*star
|
|||
return __pthread_create_js(thread, attr, start_routine, arg);
|
||||
}
|
||||
|
||||
void _emscripten_thread_exit(void* retval) {
|
||||
assert(pthread_self());
|
||||
__pthread_exit_js(retval);
|
||||
void _emscripten_thread_exit(void* result) {
|
||||
struct pthread *self = __pthread_self();
|
||||
assert(self);
|
||||
|
||||
self->canceldisable = PTHREAD_CANCEL_DISABLE;
|
||||
self->cancelasync = PTHREAD_CANCEL_DEFERRED;
|
||||
self->result = result;
|
||||
|
||||
__pthread_exit_run_handlers();
|
||||
|
||||
// Call into the musl function that runs destructors of all thread-specific data.
|
||||
__pthread_tsd_run_dtors();
|
||||
|
||||
if (self == emscripten_main_browser_thread_id()) {
|
||||
// FIXME(sbc): When pthread_exit causes the entire application to exit
|
||||
// we should be returning zero (according to the man page for pthread_exit).
|
||||
exit((intptr_t)result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark the thread as no longer running.
|
||||
// When we publish this, the main thread is free to deallocate the thread object and we are done.
|
||||
self->threadStatus = 1;
|
||||
|
||||
emscripten_futex_wake(&self->threadStatus, INT_MAX); // wake all threads
|
||||
|
||||
// Not hosting a pthread anymore in this worker, reset the info structures to null.
|
||||
_emscripten_thread_init(0, 0, 0); // Unregister the thread block inside the wasm module.
|
||||
__pthread_exit_done();
|
||||
}
|
||||
|
||||
// Mark as `no_sanitize("address"` since emscripten_pthread_exit destroys
|
||||
|
|
|
@ -14,8 +14,7 @@ M
|
|||
N
|
||||
O
|
||||
P
|
||||
t
|
||||
u
|
||||
Q
|
||||
v
|
||||
w
|
||||
x
|
||||
|
|
|
@ -7,7 +7,6 @@ $__pthread_mutex_trylock
|
|||
$__pthread_mutex_unlock
|
||||
$__pthread_self_internal
|
||||
$__pthread_setcancelstate
|
||||
$__pthread_tsd_run_dtors
|
||||
$__wasm_call_ctors
|
||||
$__wasm_init_memory
|
||||
$_do_call
|
||||
|
|
|
@ -17,3 +17,5 @@ a.p
|
|||
a.q
|
||||
a.r
|
||||
a.s
|
||||
a.t
|
||||
a.u
|
||||
|
|
|
@ -17,3 +17,5 @@ p
|
|||
q
|
||||
r
|
||||
s
|
||||
t
|
||||
u
|
||||
|
|
Загрузка…
Ссылка в новой задаче