diff options
author | Damiano Mazzella <damianomazzella@gmail.com> | 2019-02-05 22:13:36 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2019-03-27 10:50:01 +1100 |
commit | 0b86ba565c3d5093620faeb0d5abdd3ff56beffa (patch) | |
tree | 35db75f4b6ec56aa084ba79cce5d8d2ce182dc45 | |
parent | 968b688055b75f3779b6d07bea0d2c1e0f3c17ba (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.c | 24 |
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); } |