Move thread exit code to native. NFC (#14853)

This commit is contained in:
Sam Clegg 2021-08-12 17:00:13 -07:00 коммит произвёл GitHub
Родитель 7e538a419c
Коммит 60de3300c4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 54 добавлений и 45 удалений

Просмотреть файл

@ -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