Skip to content

Commit 853dc6b

Browse files
committed
darwin: add threading support and use it by default
1 parent 120d17c commit 853dc6b

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

Diff for: compileopts/target.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
385385
platformVersion = "11.0.0" // first macosx platform with arm64 support
386386
}
387387
llvmvendor = "apple"
388-
spec.Scheduler = "tasks"
388+
spec.Scheduler = "threads"
389389
spec.Linker = "ld.lld"
390390
spec.Libc = "darwin-libSystem"
391391
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
@@ -399,6 +399,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
399399
)
400400
spec.ExtraFiles = append(spec.ExtraFiles,
401401
"src/internal/futex/futex_darwin.c",
402+
"src/internal/task/task_threads.c",
402403
"src/runtime/os_darwin.c",
403404
"src/runtime/runtime_unix.c",
404405
"src/runtime/signal.c")

Diff for: src/internal/task/darwin.go

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//go:build darwin
2+
3+
package task
4+
5+
import "unsafe"
6+
7+
// MacOS uses a pointer so unsafe.Pointer should be fine:
8+
//
9+
// typedef struct _opaque_pthread_t *__darwin_pthread_t;
10+
// typedef __darwin_pthread_t pthread_t;
11+
type threadID unsafe.Pointer

Diff for: src/internal/task/task_threads.c

+27-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,23 @@
22

33
#define _GNU_SOURCE
44
#include <pthread.h>
5-
#include <semaphore.h>
65
#include <signal.h>
76
#include <stdint.h>
87
#include <stdio.h>
98

10-
// BDWGC also uses SIGRTMIN+6 on Linux, which seems like a reasonable choice.
119
#ifdef __linux__
10+
#include <semaphore.h>
11+
12+
// BDWGC also uses SIGRTMIN+6 on Linux, which seems like a reasonable choice.
1213
#define taskPauseSignal (SIGRTMIN + 6)
13-
#endif
14+
15+
#elif __APPLE__
16+
#include <dispatch/dispatch.h>
17+
// Use an arbitrary signal number (31-63) in the hope that it isn't used
18+
// elsewhere.
19+
#define taskPauseSignal 60
20+
21+
#endif // __linux__, __APPLE__
1422

1523
// Pointer to the current task.Task structure.
1624
// Ideally the entire task.Task structure would be a thread-local variable but
@@ -22,7 +30,11 @@ struct state_pass {
2230
void *args;
2331
void *task;
2432
uintptr_t *stackTop;
33+
#if __APPLE__
34+
dispatch_semaphore_t startlock;
35+
#else
2536
sem_t startlock;
37+
#endif
2638
};
2739

2840
// Handle the GC pause in Go.
@@ -60,7 +72,11 @@ static void* start_wrapper(void *arg) {
6072

6173
// Notify the caller that the thread has successfully started and
6274
// initialized.
75+
#if __APPLE__
76+
dispatch_semaphore_signal(state->startlock);
77+
#else
6378
sem_post(&state->startlock);
79+
#endif
6480

6581
// Run the goroutine function.
6682
start(args);
@@ -84,11 +100,19 @@ int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, u
84100
.task = task,
85101
.stackTop = stackTop,
86102
};
103+
#if __APPLE__
104+
state.startlock = dispatch_semaphore_create(0);
105+
#else
87106
sem_init(&state.startlock, 0, 0);
107+
#endif
88108
int result = pthread_create(thread, NULL, &start_wrapper, &state);
89109

90110
// Wait until the thread has been created and read all state_pass variables.
111+
#if __APPLE__
112+
dispatch_semaphore_wait(state.startlock, DISPATCH_TIME_FOREVER);
113+
#else
91114
sem_wait(&state.startlock);
115+
#endif
92116

93117
return result;
94118
}

0 commit comments

Comments
 (0)