Make POSIX threads improvements

- Ensure SIGTHR isn't blocked in newly created threads
- Use TIB rather than thread_local for thread atexits
- Make POSIX thread keys atomic within thread
- Don't bother logging prctl() to --strace
- Log thread destructor names to --strace
This commit is contained in:
Justine Tunney 2024-06-30 15:38:59 -07:00
parent 387310c659
commit 76957983cf
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
11 changed files with 57 additions and 71 deletions

View file

@ -54,9 +54,8 @@ long _pthread_cancel_ack(void) {
pthread_exit(PTHREAD_CANCELED);
}
pt->pt_flags |= PT_NOCANCEL;
if (IsOpenbsd()) {
if (IsOpenbsd())
pt->pt_flags |= PT_OPENBSD_KLUDGE;
}
return ecanceled();
}
@ -351,6 +350,7 @@ static errno_t _pthread_cancel_everyone(void) {
* @param thread may be 0 to cancel all threads except self
* @return 0 on success, or errno on error
* @raise ESRCH if system thread wasn't alive or we lost a race
* @cancelationpoint
*/
errno_t pthread_cancel(pthread_t thread) {
struct PosixThread *arg;
@ -401,6 +401,7 @@ void pthread_testcancel(void) {
*
* @return 0 if not cancelled or cancelation is blocked or `ECANCELED`
* in masked mode when the calling thread has been cancelled
* @cancelationpoint
*/
errno_t pthread_testcancel_np(void) {
struct PosixThread *pt;

View file

@ -117,6 +117,7 @@ static int PosixThread(void *arg, int tid) {
}
// set long jump handler so pthread_exit can bring control back here
if (!setjmp(pt->pt_exiter)) {
sigdelset(&pt->pt_attr.__sigmask, SIGTHR);
if (IsWindows()) {
atomic_store_explicit(&__get_tls()->tib_sigmask, pt->pt_attr.__sigmask,
memory_order_release);

View file

@ -48,9 +48,9 @@ int pthread_key_create(pthread_key_t *key, pthread_key_dtor dtor) {
if (!dtor)
dtor = (pthread_key_dtor)-1;
for (i = 0; i < PTHREAD_KEYS_MAX; ++i) {
if (!(expect = atomic_load_explicit(_pthread_key_dtor + i,
memory_order_acquire)) &&
atomic_compare_exchange_strong_explicit(_pthread_key_dtor + i, &expect,
if (!(expect = atomic_load_explicit(&_pthread_key_dtor[i],
memory_order_relaxed)) &&
atomic_compare_exchange_strong_explicit(&_pthread_key_dtor[i], &expect,
dtor, memory_order_release,
memory_order_relaxed)) {
*key = i;

View file

@ -16,7 +16,6 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
#include "libc/thread/posixthread.internal.h"
@ -32,10 +31,12 @@
*
* @param key was created by pthread_key_create()
* @return 0 on success, or errno on error
* @raise EINVAL if `key` is invalid
*/
int pthread_key_delete(pthread_key_t k) {
unassert(0 <= k && k < PTHREAD_KEYS_MAX);
unassert(atomic_load_explicit(_pthread_key_dtor + k, memory_order_acquire));
atomic_store_explicit(_pthread_key_dtor + k, 0, memory_order_release);
if (!(0 <= k && k < PTHREAD_KEYS_MAX))
return EINVAL; // corrupt key identifier
if (!atomic_exchange_explicit(&_pthread_key_dtor[k], 0, memory_order_acq_rel))
return EINVAL; // delete called twice
return 0;
}

View file

@ -1,7 +1,7 @@
#ifndef COSMOPOLITAN_LIBC_THREAD_THREAD_H_
#define COSMOPOLITAN_LIBC_THREAD_THREAD_H_
#define PTHREAD_KEYS_MAX 48
#define PTHREAD_KEYS_MAX 46
#define PTHREAD_STACK_MIN 65536
#define PTHREAD_DESTRUCTOR_ITERATIONS 4

View file

@ -39,7 +39,8 @@ struct CosmoTib {
uint32_t tib_sigstack_flags;
_Atomic(int) tib_relock_maps;
void *tib_nsync;
void *tib_keys[47];
void *tib_atexit;
_Atomic(void *) tib_keys[46];
} __attribute__((__aligned__(64)));
extern int __threaded;