2
2
3
3
#define _GNU_SOURCE
4
4
#include <pthread.h>
5
- #include <semaphore.h>
6
5
#include <signal.h>
7
6
#include <stdint.h>
8
7
#include <stdio.h>
9
8
#include <unistd.h>
10
9
11
- // BDWGC also uses SIGRTMIN+6 on Linux, which seems like a reasonable choice.
12
10
#ifdef __linux__
11
+ #include <semaphore.h>
12
+
13
+ // BDWGC also uses SIGRTMIN+6 on Linux, which seems like a reasonable choice.
13
14
#define taskPauseSignal (SIGRTMIN + 6)
14
- #endif
15
+
16
+ #elif __APPLE__
17
+ #include <dispatch/dispatch.h>
18
+ // SIGIO is for interrupt-driven I/O.
19
+ // I don't think anybody should be using this nowadays, so I think we can
20
+ // repurpose it as a signal for GC.
21
+ // BDWGC uses a special way to pause/resume other threads on MacOS, which may be
22
+ // better but needs more work. Using signal keeps the code similar between Linux
23
+ // and MacOS.
24
+ #define taskPauseSignal SIGIO
25
+
26
+ #endif // __linux__, __APPLE__
15
27
16
28
// Pointer to the current task.Task structure.
17
29
// Ideally the entire task.Task structure would be a thread-local variable but
@@ -23,7 +35,11 @@ struct state_pass {
23
35
void * args ;
24
36
void * task ;
25
37
uintptr_t * stackTop ;
38
+ #if __APPLE__
39
+ dispatch_semaphore_t startlock ;
40
+ #else
26
41
sem_t startlock ;
42
+ #endif
27
43
};
28
44
29
45
// Handle the GC pause in Go.
@@ -68,7 +84,11 @@ static void* start_wrapper(void *arg) {
68
84
69
85
// Notify the caller that the thread has successfully started and
70
86
// initialized.
87
+ #if __APPLE__
88
+ dispatch_semaphore_signal (state -> startlock );
89
+ #else
71
90
sem_post (& state -> startlock );
91
+ #endif
72
92
73
93
// Run the goroutine function.
74
94
start (args );
@@ -92,11 +112,19 @@ int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, u
92
112
.task = task ,
93
113
.stackTop = stackTop ,
94
114
};
115
+ #if __APPLE__
116
+ state .startlock = dispatch_semaphore_create (0 );
117
+ #else
95
118
sem_init (& state .startlock , 0 , 0 );
119
+ #endif
96
120
int result = pthread_create (thread , NULL , & start_wrapper , & state );
97
121
98
122
// Wait until the thread has been created and read all state_pass variables.
123
+ #if __APPLE__
124
+ dispatch_semaphore_wait (state .startlock , DISPATCH_TIME_FOREVER );
125
+ #else
99
126
sem_wait (& state .startlock );
127
+ #endif
100
128
101
129
return result ;
102
130
}
0 commit comments