mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-03 02:27:48 +00:00
darwin: add threading support and use it by default
This commit is contained in:
committed by
Ron Evans
parent
93f40992c1
commit
0e43146d32
@@ -385,7 +385,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
platformVersion = "11.0.0" // first macosx platform with arm64 support
|
||||
}
|
||||
llvmvendor = "apple"
|
||||
spec.Scheduler = "tasks"
|
||||
spec.Scheduler = "threads"
|
||||
spec.Linker = "ld.lld"
|
||||
spec.Libc = "darwin-libSystem"
|
||||
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
|
||||
@@ -399,6 +399,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
||||
)
|
||||
spec.ExtraFiles = append(spec.ExtraFiles,
|
||||
"src/internal/futex/futex_darwin.c",
|
||||
"src/internal/task/task_threads.c",
|
||||
"src/runtime/os_darwin.c",
|
||||
"src/runtime/runtime_unix.c",
|
||||
"src/runtime/signal.c")
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
//go:build darwin
|
||||
|
||||
package task
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// MacOS uses a pointer so unsafe.Pointer should be fine:
|
||||
//
|
||||
// typedef struct _opaque_pthread_t *__darwin_pthread_t;
|
||||
// typedef __darwin_pthread_t pthread_t;
|
||||
type threadID unsafe.Pointer
|
||||
@@ -2,16 +2,28 @@
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// BDWGC also uses SIGRTMIN+6 on Linux, which seems like a reasonable choice.
|
||||
#ifdef __linux__
|
||||
#include <semaphore.h>
|
||||
|
||||
// BDWGC also uses SIGRTMIN+6 on Linux, which seems like a reasonable choice.
|
||||
#define taskPauseSignal (SIGRTMIN + 6)
|
||||
#endif
|
||||
|
||||
#elif __APPLE__
|
||||
#include <dispatch/dispatch.h>
|
||||
// SIGIO is for interrupt-driven I/O.
|
||||
// I don't think anybody should be using this nowadays, so I think we can
|
||||
// repurpose it as a signal for GC.
|
||||
// BDWGC uses a special way to pause/resume other threads on MacOS, which may be
|
||||
// better but needs more work. Using signal keeps the code similar between Linux
|
||||
// and MacOS.
|
||||
#define taskPauseSignal SIGIO
|
||||
|
||||
#endif // __linux__, __APPLE__
|
||||
|
||||
// Pointer to the current task.Task structure.
|
||||
// Ideally the entire task.Task structure would be a thread-local variable but
|
||||
@@ -23,7 +35,11 @@ struct state_pass {
|
||||
void *args;
|
||||
void *task;
|
||||
uintptr_t *stackTop;
|
||||
#if __APPLE__
|
||||
dispatch_semaphore_t startlock;
|
||||
#else
|
||||
sem_t startlock;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Handle the GC pause in Go.
|
||||
@@ -68,7 +84,11 @@ static void* start_wrapper(void *arg) {
|
||||
|
||||
// Notify the caller that the thread has successfully started and
|
||||
// initialized.
|
||||
#if __APPLE__
|
||||
dispatch_semaphore_signal(state->startlock);
|
||||
#else
|
||||
sem_post(&state->startlock);
|
||||
#endif
|
||||
|
||||
// Run the goroutine function.
|
||||
start(args);
|
||||
@@ -92,11 +112,19 @@ int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, u
|
||||
.task = task,
|
||||
.stackTop = stackTop,
|
||||
};
|
||||
#if __APPLE__
|
||||
state.startlock = dispatch_semaphore_create(0);
|
||||
#else
|
||||
sem_init(&state.startlock, 0, 0);
|
||||
#endif
|
||||
int result = pthread_create(thread, NULL, &start_wrapper, &state);
|
||||
|
||||
// Wait until the thread has been created and read all state_pass variables.
|
||||
#if __APPLE__
|
||||
dispatch_semaphore_wait(state.startlock, DISPATCH_TIME_FOREVER);
|
||||
#else
|
||||
sem_wait(&state.startlock);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user