Skip to content

Commit 0e2b1bf

Browse files
committed
Make garbage collection thread safe
- You can now use _gc(malloc()) in multithreaded programs - This change fixes a bug where fork() on NT disabled TLS - Fixed TLS code morphing on XNU/NT, for R8-R15 registers
1 parent 571c2c3 commit 0e2b1bf

37 files changed

+310
-189
lines changed

examples/compress.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
╚─────────────────────────────────────────────────────────────────*/
99
#endif
1010
#include "libc/assert.h"
11+
#include "libc/calls/calls.h"
1112
#include "libc/errno.h"
1213
#include "libc/fmt/conv.h"
1314
#include "libc/log/check.h"

examples/decompress.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
╚─────────────────────────────────────────────────────────────────*/
99
#endif
1010
#include "libc/assert.h"
11+
#include "libc/calls/calls.h"
1112
#include "libc/errno.h"
1213
#include "libc/mem/mem.h"
1314
#include "libc/runtime/gc.internal.h"

libc/integral/c.inc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,10 +591,10 @@ typedef struct {
591591
#endif
592592
#endif
593593

594-
#define notpossible \
595-
do { \
596-
asm("ud2"); \
597-
unreachable; \
594+
#define notpossible \
595+
do { \
596+
asm("ud2\nnop"); \
597+
unreachable; \
598598
} while (0)
599599

600600
#define donothing \

libc/intrin/asan.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
#include "libc/mem/mem.h"
4141
#include "libc/mem/reverse.internal.h"
4242
#include "libc/nexgen32e/gc.internal.h"
43+
#include "libc/nexgen32e/gettls.h"
4344
#include "libc/nexgen32e/stackframe.h"
45+
#include "libc/nexgen32e/threaded.h"
4446
#include "libc/nt/enum/version.h"
4547
#include "libc/nt/runtime.h"
4648
#include "libc/runtime/directmap.internal.h"
@@ -56,6 +58,7 @@
5658
#include "libc/sysv/consts/nr.h"
5759
#include "libc/sysv/consts/prot.h"
5860
#include "libc/sysv/errfuns.h"
61+
#include "libc/thread/thread.h"
5962
#include "third_party/dlmalloc/dlmalloc.h"
6063

6164
STATIC_YOINK("_init_asan");
@@ -936,7 +939,7 @@ static void __asan_trace(struct AsanTrace *bt, const struct StackFrame *bp) {
936939
size_t i, gi;
937940
intptr_t addr;
938941
struct Garbages *garbage;
939-
garbage = weaken(__garbage);
942+
garbage = __tls_enabled ? ((cthread_t)__get_tls())->garbages : 0;
940943
gi = garbage ? garbage->i : 0;
941944
for (f1 = -1, i = 0; bp && i < ARRAYLEN(bt->p); ++i, bp = bp->next) {
942945
if (f1 != (f2 = ((intptr_t)bp >> 16))) {

libc/intrin/tlsisrequired.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
2+
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
3+
╞══════════════════════════════════════════════════════════════════════════════╡
4+
│ Copyright 2022 Justine Alexandra Roberts Tunney │
5+
│ │
6+
│ Permission to use, copy, modify, and/or distribute this software for │
7+
│ any purpose with or without fee is hereby granted, provided that the │
8+
│ above copyright notice and this permission notice appear in all copies. │
9+
│ │
10+
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
11+
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
12+
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
13+
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
14+
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
15+
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
16+
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17+
│ PERFORMANCE OF THIS SOFTWARE. │
18+
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/nexgen32e/threaded.h"
20+
21+
void TlsIsRequired(void) {
22+
if (!__tls_enabled) {
23+
notpossible;
24+
}
25+
}

libc/log/backtrace2.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
#include "libc/mem/alg.h"
3838
#include "libc/mem/bisectcarleft.internal.h"
3939
#include "libc/nexgen32e/gc.internal.h"
40+
#include "libc/nexgen32e/gettls.h"
41+
#include "libc/nexgen32e/threaded.h"
4042
#include "libc/runtime/gc.internal.h"
4143
#include "libc/runtime/runtime.h"
4244
#include "libc/runtime/stack.h"
@@ -47,6 +49,7 @@
4749
#include "libc/sysv/consts/fileno.h"
4850
#include "libc/sysv/consts/o.h"
4951
#include "libc/sysv/consts/sig.h"
52+
#include "libc/thread/thread.h"
5053
#include "libc/x/x.h"
5154

5255
#define kBacktraceMaxFrames 128
@@ -106,7 +109,7 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
106109
argv[i++] = "-a"; /* filter out w/ shell script wrapper for old versions */
107110
argv[i++] = "-pCife";
108111
argv[i++] = debugbin;
109-
garbage = weaken(__garbage);
112+
garbage = __tls_enabled ? ((cthread_t)__get_tls())->garbages : 0;
110113
gi = garbage ? garbage->i : 0;
111114
for (frame = bp; frame && i < kBacktraceMaxFrames - 1; frame = frame->next) {
112115
addr = frame->addr;

libc/log/backtrace3.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,24 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19-
#include "libc/mem/bisectcarleft.internal.h"
2019
#include "libc/assert.h"
21-
#include "libc/intrin/weaken.h"
2220
#include "libc/calls/calls.h"
2321
#include "libc/fmt/fmt.h"
2422
#include "libc/fmt/itoa.h"
2523
#include "libc/intrin/kprintf.h"
24+
#include "libc/intrin/weaken.h"
2625
#include "libc/log/backtrace.internal.h"
2726
#include "libc/macros.internal.h"
27+
#include "libc/mem/bisectcarleft.internal.h"
2828
#include "libc/nexgen32e/gc.internal.h"
29+
#include "libc/nexgen32e/gettls.h"
2930
#include "libc/nexgen32e/stackframe.h"
31+
#include "libc/nexgen32e/threaded.h"
3032
#include "libc/runtime/memtrack.internal.h"
3133
#include "libc/runtime/runtime.h"
3234
#include "libc/runtime/symbols.internal.h"
3335
#include "libc/str/str.h"
36+
#include "libc/thread/thread.h"
3437

3538
#define LIMIT 100
3639

@@ -54,7 +57,7 @@ noinstrument noasan int PrintBacktraceUsingSymbols(int fd,
5457
struct Garbages *garbage;
5558
const struct StackFrame *frame;
5659
if (!bp) bp = __builtin_frame_address(0);
57-
garbage = weaken(__garbage);
60+
garbage = __tls_enabled ? ((cthread_t)__get_tls())->garbages : 0;
5861
gi = garbage ? garbage->i : 0;
5962
for (i = 0, frame = bp; frame; frame = frame->next) {
6063
if (++i == LIMIT) {

libc/log/log.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ o/$(MODE)/libc/log/watch.o: private \
6969
OVERRIDE_CFLAGS += \
7070
-ffreestanding
7171

72+
o/$(MODE)/libc/log/watch.o \
7273
o/$(MODE)/libc/log/attachdebugger.o \
7374
o/$(MODE)/libc/log/checkaligned.o \
7475
o/$(MODE)/libc/log/checkfail.o \

libc/log/printgarbage.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
#include "libc/intrin/kprintf.h"
2121
#include "libc/log/log.h"
2222
#include "libc/nexgen32e/gc.internal.h"
23+
#include "libc/nexgen32e/gettls.h"
24+
#include "libc/nexgen32e/threaded.h"
2325
#include "libc/stdio/stdio.h"
24-
/* clang-format off */
26+
#include "libc/thread/thread.h"
27+
// clang-format off
2528

2629
/**
2730
* Prints list of deferred operations on shadow stack.
@@ -30,24 +33,25 @@ void PrintGarbage(void) {
3033
size_t i;
3134
char name[19];
3235
const char *symbol;
36+
struct Garbages *g;
3337
kprintf("\n");
3438
kprintf(" SHADOW STACK @ %p\n", __builtin_frame_address(0));
3539
kprintf("garbage ent. parent frame original ret callback arg \n");
3640
kprintf("------------ ------------ ------------------ ------------------ ------------------\n");
37-
if (__garbage.i) {
38-
for (i = __garbage.i; i--;) {
39-
symbol = __get_symbol_by_addr(__garbage.p[i].ret);
41+
if ((g = __tls_enabled ? ((cthread_t)__get_tls())->garbages:0) && g->i) {
42+
for (i = g->i; i--;) {
43+
symbol = __get_symbol_by_addr(g->p[i].ret);
4044
if (symbol) {
4145
ksnprintf(name, sizeof(name), "%s", symbol);
4246
} else {
43-
ksnprintf(name, sizeof(name), "%#014lx", __garbage.p[i].ret);
47+
ksnprintf(name, sizeof(name), "%#014lx", g->p[i].ret);
4448
}
4549
kprintf("%12lx %12lx %18s %18s %#18lx\n",
46-
__garbage.p + i,
47-
__garbage.p[i].frame,
50+
g->p + i,
51+
g->p[i].frame,
4852
name,
49-
__get_symbol_by_addr(__garbage.p[i].fn),
50-
__garbage.p[i].arg);
53+
__get_symbol_by_addr(g->p[i].fn),
54+
g->p[i].arg);
5155
}
5256
} else {
5357
kprintf("%12s %12s %18s %18s %18s\n","empty","-","-","-","-");

libc/mem/_gc_free.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
2+
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
3+
╞══════════════════════════════════════════════════════════════════════════════╡
4+
│ Copyright 2022 Justine Alexandra Roberts Tunney │
5+
│ │
6+
│ Permission to use, copy, modify, and/or distribute this software for │
7+
│ any purpose with or without fee is hereby granted, provided that the │
8+
│ above copyright notice and this permission notice appear in all copies. │
9+
│ │
10+
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
11+
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
12+
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
13+
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
14+
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
15+
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
16+
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17+
│ PERFORMANCE OF THIS SOFTWARE. │
18+
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/mem/mem.h"
20+
#include "libc/runtime/gc.h"
21+
22+
void _gc_free(void *p) {
23+
free(p);
24+
}

0 commit comments

Comments
 (0)