Skip to content

Commit db9ea61

Browse files
committed
darwin: add threading support and use it by default
1 parent aa5d21f commit db9ea61

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,16 +2,24 @@
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
#include <unistd.h>
109

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

1624
// Pointer to the current task.Task structure.
1725
// Ideally the entire task.Task structure would be a thread-local variable but
@@ -23,7 +31,11 @@ struct state_pass {
2331
void *args;
2432
void *task;
2533
uintptr_t *stackTop;
34+
#if __APPLE__
35+
dispatch_semaphore_t startlock;
36+
#else
2637
sem_t startlock;
38+
#endif
2739
};
2840

2941
// Handle the GC pause in Go.
@@ -69,7 +81,11 @@ static void* start_wrapper(void *arg) {
6981

7082
// Notify the caller that the thread has successfully started and
7183
// initialized.
84+
#if __APPLE__
85+
dispatch_semaphore_signal(state->startlock);
86+
#else
7287
sem_post(&state->startlock);
88+
#endif
7389

7490
// Run the goroutine function.
7591
start(args);
@@ -93,11 +109,19 @@ int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, u
93109
.task = task,
94110
.stackTop = stackTop,
95111
};
112+
#if __APPLE__
113+
state.startlock = dispatch_semaphore_create(0);
114+
#else
96115
sem_init(&state.startlock, 0, 0);
116+
#endif
97117
int result = pthread_create(thread, NULL, &start_wrapper, &state);
98118

99119
// Wait until the thread has been created and read all state_pass variables.
120+
#if __APPLE__
121+
dispatch_semaphore_wait(state.startlock, DISPATCH_TIME_FOREVER);
122+
#else
100123
sem_wait(&state.startlock);
124+
#endif
101125

102126
return result;
103127
}

0 commit comments

Comments
 (0)