Skip to content

Commit 7695798

Browse files
committed
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
1 parent 387310c commit 7695798

File tree

11 files changed

+57
-71
lines changed

11 files changed

+57
-71
lines changed

libc/calls/prctl.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,5 @@ int prctl(int operation, ...) {
5353
rc = enosys();
5454
}
5555

56-
#if SYSDEBUG
57-
if (operation == PR_CAPBSET_READ || operation == PR_CAPBSET_DROP) {
58-
STRACE("prctl(%s, %s) → %d% m", DescribePrctlOperation(operation),
59-
DescribeCapability(a), rc);
60-
} else {
61-
STRACE("prctl(%s, %p, %p, %p, %p) → %d% m",
62-
DescribePrctlOperation(operation), a, b, c, d, rc);
63-
}
64-
#endif
65-
6656
return rc;
6757
}

libc/intrin/describeflags.internal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const char *DescribeFlags(char *, size_t, const struct DescribeFlags *, size_t,
1313

1414
const char *DescribeArchPrctlCode(char[12], int) libcesque;
1515
const char *DescribeCancelState(char[12], int, int *) libcesque;
16-
const char *DescribeCapability(char[32], int) libcesque;
1716
const char *DescribeClockName(char[32], int) libcesque;
1817
const char *DescribeControlKeyState(char[64], uint32_t) libcesque;
1918
const char *DescribeDirfd(char[12], int) libcesque;
@@ -47,7 +46,6 @@ const char *DescribeOpenFlags(char[128], int) libcesque;
4746
const char *DescribeOpenMode(char[15], int, int) libcesque;
4847
const char *DescribePersonalityFlags(char[128], int) libcesque;
4948
const char *DescribePollFlags(char[64], int) libcesque;
50-
const char *DescribePrctlOperation(int) libcesque;
5149
const char *DescribeProtFlags(char[48], int) libcesque;
5250
const char *DescribePtrace(char[12], int) libcesque;
5351
const char *DescribePtraceEvent(char[32], int) libcesque;
@@ -69,9 +67,7 @@ const char *DescribeVirtualKeyCode(char[32], uint32_t) libcesque;
6967
const char *DescribeWhence(char[12], int) libcesque;
7068
const char *DescribeWhichPrio(char[12], int) libcesque;
7169

72-
#define DescribeArchPrctlCode(x) DescribeArchPrctlCode(alloca(12), x)
7370
#define DescribeCancelState(x, y) DescribeCancelState(alloca(12), x, y)
74-
#define DescribeCapability(x) DescribeCapability(alloca(32), x)
7571
#define DescribeClockName(x) DescribeClockName(alloca(32), x)
7672
#define DescribeControlKeyState(x) DescribeControlKeyState(alloca(64), x)
7773
#define DescribeDirfd(x) DescribeDirfd(alloca(12), x)

libc/runtime/cxa_thread_atexit.c

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/intrin/cxaatexit.internal.h"
20+
#include "libc/intrin/strace.internal.h"
2021
#include "libc/intrin/weaken.h"
2122
#include "libc/mem/mem.h"
2223
#include "libc/nexgen32e/gc.internal.h"
@@ -30,8 +31,6 @@ struct Dtor {
3031
struct Dtor *next;
3132
};
3233

33-
static _Thread_local struct Dtor *__cxa_thread_atexit_list;
34-
3534
static void _pthread_unwind(struct CosmoTib *tib) {
3635
struct PosixThread *pt;
3736
struct _pthread_cleanup_buffer *cb;
@@ -42,34 +41,33 @@ static void _pthread_unwind(struct CosmoTib *tib) {
4241
}
4342
}
4443

45-
static void __cxa_thread_unkey(struct CosmoTib *tib) {
46-
void *val;
47-
int i, j, gotsome;
48-
pthread_key_dtor dtor;
49-
for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; ++j) {
50-
for (gotsome = i = 0; i < PTHREAD_KEYS_MAX; ++i) {
51-
if ((val = tib->tib_keys[i]) &&
52-
(dtor = atomic_load_explicit(_pthread_key_dtor + i,
53-
memory_order_relaxed)) &&
54-
dtor != (pthread_key_dtor)-1) {
55-
gotsome = 1;
56-
tib->tib_keys[i] = 0;
44+
static void _pthread_unkey(struct CosmoTib *tib) {
45+
for (int j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; ++j) {
46+
bool gotsome = false;
47+
for (int i = 0; i < PTHREAD_KEYS_MAX; ++i) {
48+
void *val;
49+
pthread_key_dtor dtor;
50+
if ((dtor = atomic_load_explicit(&_pthread_key_dtor[i],
51+
memory_order_acquire)) &&
52+
dtor != (pthread_key_dtor)-1 &&
53+
(val = atomic_exchange_explicit(&tib->tib_keys[i], 0,
54+
memory_order_relaxed))) {
55+
STRACE("_pthread_unkey(%t, %p)", dtor, val);
56+
gotsome = true;
5757
dtor(val);
5858
}
5959
}
60-
if (!gotsome) {
60+
if (!gotsome)
6161
break;
62-
}
6362
}
6463
}
6564

6665
static void _pthread_ungarbage(struct CosmoTib *tib) {
6766
struct Garbages *g;
6867
while ((g = tib->tib_garbages)) {
6968
tib->tib_garbages = 0;
70-
while (g->i--) {
69+
while (g->i--)
7170
((void (*)(intptr_t))g->p[g->i].fn)(g->p[g->i].arg);
72-
}
7371
_weaken(free)(g->p);
7472
_weaken(free)(g);
7573
}
@@ -82,10 +80,11 @@ void __cxa_thread_finalize(void) {
8280
_pthread_unwind(tib);
8381
if (tib->tib_nsync)
8482
_weaken(nsync_waiter_destroy)(tib->tib_nsync);
85-
__cxa_thread_unkey(tib);
83+
_pthread_unkey(tib);
8684
_pthread_ungarbage(tib);
87-
while ((dtor = __cxa_thread_atexit_list)) {
88-
__cxa_thread_atexit_list = dtor->next;
85+
while ((dtor = tib->tib_atexit)) {
86+
STRACE("__cxa_finalize(%t, %p)", dtor->fun, dtor->arg);
87+
tib->tib_atexit = dtor->next;
8988
((void (*)(void *))dtor->fun)(dtor->arg);
9089
_weaken(free)(dtor);
9190
}
@@ -97,9 +96,11 @@ int __cxa_thread_atexit_impl(void *fun, void *arg, void *dso_symbol) {
9796
return -1;
9897
if (!(dtor = _weaken(malloc)(sizeof(struct Dtor))))
9998
return -1;
99+
struct CosmoTib *tib;
100+
tib = __get_tls();
100101
dtor->fun = fun;
101102
dtor->arg = arg;
102-
dtor->next = __cxa_thread_atexit_list;
103-
__cxa_thread_atexit_list = dtor;
103+
dtor->next = tib->tib_atexit;
104+
tib->tib_atexit = dtor;
104105
return 0;
105106
}

libc/thread/pthread_cancel.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ long _pthread_cancel_ack(void) {
5454
pthread_exit(PTHREAD_CANCELED);
5555
}
5656
pt->pt_flags |= PT_NOCANCEL;
57-
if (IsOpenbsd()) {
57+
if (IsOpenbsd())
5858
pt->pt_flags |= PT_OPENBSD_KLUDGE;
59-
}
6059
return ecanceled();
6160
}
6261

@@ -351,6 +350,7 @@ static errno_t _pthread_cancel_everyone(void) {
351350
* @param thread may be 0 to cancel all threads except self
352351
* @return 0 on success, or errno on error
353352
* @raise ESRCH if system thread wasn't alive or we lost a race
353+
* @cancelationpoint
354354
*/
355355
errno_t pthread_cancel(pthread_t thread) {
356356
struct PosixThread *arg;
@@ -401,6 +401,7 @@ void pthread_testcancel(void) {
401401
*
402402
* @return 0 if not cancelled or cancelation is blocked or `ECANCELED`
403403
* in masked mode when the calling thread has been cancelled
404+
* @cancelationpoint
404405
*/
405406
errno_t pthread_testcancel_np(void) {
406407
struct PosixThread *pt;

libc/thread/pthread_create.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ static int PosixThread(void *arg, int tid) {
117117
}
118118
// set long jump handler so pthread_exit can bring control back here
119119
if (!setjmp(pt->pt_exiter)) {
120+
sigdelset(&pt->pt_attr.__sigmask, SIGTHR);
120121
if (IsWindows()) {
121122
atomic_store_explicit(&__get_tls()->tib_sigmask, pt->pt_attr.__sigmask,
122123
memory_order_release);

libc/thread/pthread_key_create.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ int pthread_key_create(pthread_key_t *key, pthread_key_dtor dtor) {
4848
if (!dtor)
4949
dtor = (pthread_key_dtor)-1;
5050
for (i = 0; i < PTHREAD_KEYS_MAX; ++i) {
51-
if (!(expect = atomic_load_explicit(_pthread_key_dtor + i,
52-
memory_order_acquire)) &&
53-
atomic_compare_exchange_strong_explicit(_pthread_key_dtor + i, &expect,
51+
if (!(expect = atomic_load_explicit(&_pthread_key_dtor[i],
52+
memory_order_relaxed)) &&
53+
atomic_compare_exchange_strong_explicit(&_pthread_key_dtor[i], &expect,
5454
dtor, memory_order_release,
5555
memory_order_relaxed)) {
5656
*key = i;

libc/thread/pthread_key_delete.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19-
#include "libc/assert.h"
2019
#include "libc/errno.h"
2120
#include "libc/intrin/atomic.h"
2221
#include "libc/thread/posixthread.internal.h"
@@ -32,10 +31,12 @@
3231
*
3332
* @param key was created by pthread_key_create()
3433
* @return 0 on success, or errno on error
34+
* @raise EINVAL if `key` is invalid
3535
*/
3636
int pthread_key_delete(pthread_key_t k) {
37-
unassert(0 <= k && k < PTHREAD_KEYS_MAX);
38-
unassert(atomic_load_explicit(_pthread_key_dtor + k, memory_order_acquire));
39-
atomic_store_explicit(_pthread_key_dtor + k, 0, memory_order_release);
37+
if (!(0 <= k && k < PTHREAD_KEYS_MAX))
38+
return EINVAL; // corrupt key identifier
39+
if (!atomic_exchange_explicit(&_pthread_key_dtor[k], 0, memory_order_acq_rel))
40+
return EINVAL; // delete called twice
4041
return 0;
4142
}

libc/thread/thread.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef COSMOPOLITAN_LIBC_THREAD_THREAD_H_
22
#define COSMOPOLITAN_LIBC_THREAD_THREAD_H_
33

4-
#define PTHREAD_KEYS_MAX 48
4+
#define PTHREAD_KEYS_MAX 46
55
#define PTHREAD_STACK_MIN 65536
66
#define PTHREAD_DESTRUCTOR_ITERATIONS 4
77

libc/thread/tls.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ struct CosmoTib {
3939
uint32_t tib_sigstack_flags;
4040
_Atomic(int) tib_relock_maps;
4141
void *tib_nsync;
42-
void *tib_keys[47];
42+
void *tib_atexit;
43+
_Atomic(void *) tib_keys[46];
4344
} __attribute__((__aligned__(64)));
4445

4546
extern int __threaded;

test/ctl/all_of_test.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
#include "ctl/array.h"
2121
#include "libc/mem/leaks.h"
2222

23-
#include <algorithm>
24-
#include <array>
25-
#define ctl std
23+
// #include <algorithm>
24+
// #include <array>
25+
// #define ctl std
2626

2727
int
2828
main()

0 commit comments

Comments
 (0)