summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamiano Mazzella <damianomazzella@gmail.com>2019-02-05 22:13:36 +0100
committerDamien George <damien.p.george@gmail.com>2019-03-27 10:50:01 +1100
commit0b86ba565c3d5093620faeb0d5abdd3ff56beffa (patch)
tree35db75f4b6ec56aa084ba79cce5d8d2ce182dc45
parent968b688055b75f3779b6d07bea0d2c1e0f3c17ba (diff)
unix/mpthreadport: Use named semaphores on Mac OS X.
Unnamed semaphores (via sem_init) are not supported on this OS. See #4465.
-rw-r--r--ports/unix/mpthreadport.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/ports/unix/mpthreadport.c b/ports/unix/mpthreadport.c
index 29f2efe75..4fe5fa921 100644
--- a/ports/unix/mpthreadport.c
+++ b/ports/unix/mpthreadport.c
@@ -34,6 +34,7 @@
#if MICROPY_PY_THREAD
+#include <fcntl.h>
#include <signal.h>
#include <sched.h>
#include <semaphore.h>
@@ -54,7 +55,12 @@ STATIC thread_t *thread;
// this is used to synchronise the signal handler of the thread
// it's needed because we can't use any pthread calls in a signal handler
+#if defined(__APPLE__)
+STATIC char thread_signal_done_name[25];
+STATIC sem_t *thread_signal_done_p;
+#else
STATIC sem_t thread_signal_done;
+#endif
// this signal handler is used to scan the regs and stack of a thread
STATIC void mp_thread_gc(int signo, siginfo_t *info, void *context) {
@@ -71,7 +77,11 @@ STATIC void mp_thread_gc(int signo, siginfo_t *info, void *context) {
void **ptrs = (void**)(void*)MP_STATE_THREAD(pystack_start);
gc_collect_root(ptrs, (MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start)) / sizeof(void*));
#endif
+ #if defined (__APPLE__)
+ sem_post(thread_signal_done_p);
+ #else
sem_post(&thread_signal_done);
+ #endif
}
}
@@ -85,7 +95,13 @@ void mp_thread_init(void) {
thread->ready = 1;
thread->arg = NULL;
thread->next = NULL;
+
+ #if defined(__APPLE__)
+ snprintf(thread_signal_done_name, sizeof(thread_signal_done_name), "micropython_sem_%d", (int)thread->id);
+ thread_signal_done_p = sem_open(thread_signal_done_name, O_CREAT | O_EXCL, 0666, 0);
+ #else
sem_init(&thread_signal_done, 0, 0);
+ #endif
// enable signal handler for garbage collection
struct sigaction sa;
@@ -104,6 +120,10 @@ void mp_thread_deinit(void) {
free(th);
}
pthread_mutex_unlock(&thread_mutex);
+ #if defined(__APPLE__)
+ sem_close(thread_signal_done_p);
+ sem_unlink(thread_signal_done_name);
+ #endif
assert(thread->id == pthread_self());
free(thread);
}
@@ -125,7 +145,11 @@ void mp_thread_gc_others(void) {
continue;
}
pthread_kill(th->id, SIGUSR1);
+ #if defined(__APPLE__)
+ sem_wait(thread_signal_done_p);
+ #else
sem_wait(&thread_signal_done);
+ #endif
}
pthread_mutex_unlock(&thread_mutex);
}