Move __cxa_thread_atexit to native code - #14489
Conversation
e338f1f to
a6a9edc
Compare
a6a9edc to
11fbd46
Compare
|
Partially split out into #14512 |
11fbd46 to
3c9eb7b
Compare
| } | ||
|
|
||
| static pthread_key_t key; | ||
| atomic_bool key_created = false; |
There was a problem hiding this comment.
This should probably be a thread_local instead of an atomic bool.
| atomic_bool key_created = false; | |
| static thread_local bool key_created = false; |
There was a problem hiding this comment.
(this seems to fix posixtest.test_pthread_exit_3_2 locally)
There was a problem hiding this comment.
IIUC pthread_key_create should only be called once from a single thread.. so this guard needs to be shared between thread, no?
Also see the comment above for why we specifically can't use TLS variables here.
There was a problem hiding this comment.
I'm not sure if it should be shared across threads or if it should only be initialized once for a single thread. Given that the dtors_alive variable in libcxxabi was also thread local, I thought the latter approach was correct here (but I might be wrong).
Also see the comment above for why we specifically can't use TLS variables here.
Ah yes, I read that comment to fast. Could the C extension __thread help here? AFAIK, that doesn't trigger the run_dtors destructor in libcxxabi and would correspond to the dtors_alive variable.
emscripten/system/lib/libcxxabi/src/cxa_thread_atexit.cpp
Lines 71 to 72 in 4d864df
There was a problem hiding this comment.
Basically we are using pthread_key_create instead of the TLS variables used by emscripten/system/lib/libcxxabi/src/cxa_thread_atexit.cpp.
There are essentially two ways to achieve TLS: You can either use C/C++ __thread builtin, or you can do it at runtime with pthread_key_create. We are using the pthread_key_create method here because we cannot use any or C++ TLS storage here because the space needed by the TLS variables themselves is freed using a __cxa_thead_atexit handler.. even if the TLS is just plain old data.
When one uses the pthread_key_create one needs to make sure that pthread_key_create is only run once. Normally this is done using pthread_once, but that also can't be used in this case because it uses pthread_cleanup_push/pop which itself uses __cxa_thead_atexit. I've tried to explain more in the commands above.
For an example of how pthread_once is normally used to call pthread_key_create see: https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_key_create.html
There was a problem hiding this comment.
Ah, I see. Thanks for the clarification! fwiw, I tried to rebase this branch locally on origin/main, but it seems that posixtest.test_pthread_exit_3_2 still fails. Do you have any idea what could be causing this?
3c9eb7b to
1bdace4
Compare
048326a to
e8269a4
Compare
d47447c to
eae80e0
Compare
We were using `__cxa_thread_atexit` to register the funtion for free'ing TLS data. And because were were running the exit handlers `__pthread_exit_run_handlers` before `__pthread_tsd_run_dtors` it meant that any pthread_key descructor functions would not be able to access TLS variables. Instead we really need to delay free'ing of TLS data until all exit handlers and pthread_key descructors have been run. This was causing failure of `lsan.test_stdio_locking` due to the fact that lsan uses TLS during pthread key destruction. Specifically `thread_finalize` (a pthread_key desctructor function) calls `ThreadFinish` which in turn calls `GetCurrentThread` which uses a thread local variable to store the current thread ID. This change should allow #14489 to be dramatically simplified because it will allow the use of TLS variables to implement the atexit queue.
We were using `__cxa_thread_atexit` to register the funtion for free'ing TLS data. And because were were running the exit handlers `__pthread_exit_run_handlers` before `__pthread_tsd_run_dtors` it meant that any pthread_key descructor functions would not be able to access TLS variables. Instead we really need to delay free'ing of TLS data until all exit handlers and pthread_key descructors have been run. This was causing failure of `lsan.test_stdio_locking` due to the fact that lsan uses TLS during pthread key destruction. Specifically `thread_finalize` (a pthread_key desctructor function) calls `ThreadFinish` which in turn calls `GetCurrentThread` which uses a thread local variable to store the current thread ID. This change should allow #14489 to be dramatically simplified because it will allow the use of TLS variables to implement the atexit queue.
We were using `__cxa_thread_atexit` to register the funtion for free'ing TLS data. And because were were running the exit handlers `__pthread_exit_run_handlers` before `__pthread_tsd_run_dtors` it meant that any pthread_key descructor functions would not be able to access TLS variables. Instead we really need to delay free'ing of TLS data until all exit handlers and pthread_key descructors have been run. This was causing failure of `lsan.test_stdio_locking` due to the fact that lsan uses TLS during pthread key destruction. Specifically `thread_finalize` (a pthread_key desctructor function) calls `ThreadFinish` which in turn calls `GetCurrentThread` which uses a thread local variable to store the current thread ID. This change should allow #14489 to be dramatically simplified because it will allow the use of TLS variables to implement the atexit queue.
We were using `__cxa_thread_atexit` to register the funtion for free'ing TLS data. And because were were running the exit handlers `__pthread_exit_run_handlers` before `__pthread_tsd_run_dtors` it meant that any pthread_key descructor functions would not be able to access TLS variables. Instead we really need to delay free'ing of TLS data until all exit handlers and pthread_key descructors have been run. This was causing failure of `lsan.test_stdio_locking` due to the fact that lsan uses TLS during pthread key destruction. Specifically `thread_finalize` (a pthread_key desctructor function) calls `ThreadFinish` which in turn calls `GetCurrentThread` which uses a thread local variable to store the current thread ID. This change should allow #14489 to be dramatically simplified because it will allow the use of TLS variables to implement the atexit queue.
We were using `__cxa_thread_atexit` to register the funtion for free'ing TLS data. And because were were running the exit handlers `__pthread_exit_run_handlers` before `__pthread_tsd_run_dtors` it meant that any pthread_key descructor functions would not be able to access TLS variables. Instead we really need to delay free'ing of TLS data until all exit handlers and pthread_key descructors have been run. This was causing failure of `lsan.test_stdio_locking` due to the fact that lsan uses TLS during pthread key destruction. Specifically `thread_finalize` (a pthread_key desctructor function) calls `ThreadFinish` which in turn calls `GetCurrentThread` which uses a thread local variable to store the current thread ID. This change should allow #14489 to be dramatically simplified because it will allow the use of TLS variables to implement the atexit queue.
We were using `__cxa_thread_atexit` to register the funtion for free'ing TLS data. And because were were running the exit handlers `__pthread_exit_run_handlers` before `__pthread_tsd_run_dtors` it meant that any pthread_key descructor functions would not be able to access TLS variables. Instead we really need to delay free'ing of TLS data until all exit handlers and pthread_key descructors have been run. This was causing failure of `lsan.test_stdio_locking` due to the fact that lsan uses TLS during pthread key destruction. Specifically `thread_finalize` (a pthread_key desctructor function) calls `ThreadFinish` which in turn calls `GetCurrentThread` which uses a thread local variable to store the current thread ID. This change should allow #14489 to be dramatically simplified because it will allow the use of TLS variables to implement the atexit queue.
We were using `__cxa_thread_atexit` to register the funtion for free'ing TLS data. And because were were running the exit handlers `__pthread_exit_run_handlers` before `__pthread_tsd_run_dtors` it meant that any pthread_key descructor functions would not be able to access TLS variables. Instead we really need to delay free'ing of TLS data until all exit handlers and pthread_key descructors have been run. This was causing failure of `lsan.test_stdio_locking` due to the fact that lsan uses TLS during pthread key destruction. Specifically `thread_finalize` (a pthread_key desctructor function) calls `ThreadFinish` which in turn calls `GetCurrentThread` which uses a thread local variable to store the current thread ID. This change should allow #14489 to be dramatically simplified because it will allow the use of TLS variables to implement the atexit queue.
We were using `__cxa_thread_atexit` to register the funtion for free'ing TLS data. And because were were running the exit handlers `__pthread_exit_run_handlers` before `__pthread_tsd_run_dtors` it meant that any pthread_key descructor functions would not be able to access TLS variables. Instead we really need to delay free'ing of TLS data until all exit handlers and pthread_key descructors have been run. This was causing failure of `lsan.test_stdio_locking` due to the fact that lsan uses TLS during pthread key destruction. Specifically `thread_finalize` (a pthread_key desctructor function) calls `ThreadFinish` which in turn calls `GetCurrentThread` which uses a thread local variable to store the current thread ID. This change should allow #14489 to be dramatically simplified because it will allow the use of TLS variables to implement the atexit queue.
eae80e0 to
9f49acf
Compare
These is no need to use `__cxa_thread_atexit` here, we can just call these functions during thread exit (which is what musl does). This also avoids references `__cxa_thread_atexit` which is normally a libc++abi symbol from C programs. Needed by (split out from) #14489.
9f49acf to
0fb0306
Compare
|
OK this change is way nicer now. Since #15086 landed we can just use the libc++abi version of this function. |
These is no need to use `__cxa_thread_atexit` here, we can just call these functions during thread exit (which is what musl does). This also avoids references `__cxa_thread_atexit` which is normally a libc++abi symbol from C programs. Needed by (split out from) #14489.
1f479cf to
2cdcb71
Compare
These is no need to use `__cxa_thread_atexit` here, we can just call these functions during thread exit (which is what musl does). This also avoids references `__cxa_thread_atexit` which is normally a libc++abi symbol from C programs. Needed by (split out from) #14489.
2cdcb71 to
baac32a
Compare
These is no need to use `__cxa_thread_atexit` here, we can just call these functions during thread exit (which is what musl does). This also avoids references `__cxa_thread_atexit` which is normally a libc++abi symbol from C programs. Needed by (split out from) #14489.
5af35f2 to
48d0d34
Compare
48d0d34 to
272673b
Compare
Back in #14489 we started using the implemenation of `__cxa_thread_atexit` from libcxxabi so this is stub should never be needed. This change also involves renaming the test from `.c` to `.cpp` since C programs don't generally have access to `__cxa_thread_atexit` (its part of libcxxabi). I also removed the call to `__cxa_thread_atexit_impl` since we don't define that anywhere in emscripten. Also run this tests with threads enabled which would have resulted in an undefined reference to `__cxa_thread_atexit_impl` previously.
Back in #14489 we started using the implemenation of `__cxa_thread_atexit` from libcxxabi so this is stub should never be needed. This change also involves renaming the test from `.c` to `.cpp` since C programs don't generally have access to `__cxa_thread_atexit` (its part of libcxxabi). I also removed the call to `__cxa_thread_atexit_impl` since we don't define that anywhere in emscripten. Also run this tests with threads enabled which would have resulted in an undefined reference to `__cxa_thread_atexit_impl` previously.
Back in emscripten-core#14489 we started using the implemenation of `__cxa_thread_atexit` from libcxxabi so this is stub should never be needed. This change also involves renaming the test from `.c` to `.cpp` since C programs don't generally have access to `__cxa_thread_atexit` (its part of libcxxabi). I also removed the call to `__cxa_thread_atexit_impl` since we don't define that anywhere in emscripten. Also run this tests with threads enabled which would have resulted in an undefined reference to `__cxa_thread_atexit_impl` previously.
Use libc++abi's version of __cxa_thread_atexit.
Followup to #14484 and #14464 which both move more of the cleanup
handling for threads and processes onto the native side.
Depends on #15210.