diff --git a/meson.build b/meson.build index 755ec7ce..108565e2 100644 --- a/meson.build +++ b/meson.build @@ -284,18 +284,34 @@ if not compilers['cpp'].has_header('pthread.h') or not compilers['cpp'].links('' global_args += '-DMKXPZ_NO_PTHREAD_H_MUTEX' endif global_args += '-DMKXPZ_NO_SEMAPHORE_H' -elif not compilers['cpp'].has_header('semaphore.h') or not compilers['cpp'].links(''' - #include - int main(void) { - sem_t sem; - sem_init(&sem, 0, 0); - sem_post(&sem); - sem_wait(&sem); - sem_destroy(&sem); - return 0; - } -''', args: link_test_args, name: 'semaphore.h sanity check') - global_args += '-DMKXPZ_NO_SEMAPHORE_H' +else + if host_system == 'darwin' or not compilers['cpp'].has_header('semaphore.h') or not compilers['cpp'].links(''' + #include + int main(void) { + sem_t sem; + sem_init(&sem, 0, 0); + sem_post(&sem); + sem_wait(&sem); + sem_destroy(&sem); + return 0; + } + ''', args: link_test_args, name: 'semaphore.h sanity check') + global_args += '-DMKXPZ_NO_SEMAPHORE_H' + endif + + if not compilers['cpp'].has_header('dispatch/dispatch.h') or not compilers['cpp'].links(''' + #include + int main(void) { + dispatch_semaphore_t sem; + sem = dispatch_semaphore_create(0); + dispatch_semaphore_signal(sem); + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + dispatch_release(sem); + return 0; + } + ''', args: link_test_args, name: 'dispatch/dispatch.h sanity check') + global_args += '-DMKXPZ_NO_DISPATCH_DISPATCH_H' + endif endif if not compilers['cpp'].has_header('pthread.h') or not compilers['cpp'].links(''' diff --git a/src/mkxp-polyfill.cpp b/src/mkxp-polyfill.cpp index 8af3831a..3af0b94b 100644 --- a/src/mkxp-polyfill.cpp +++ b/src/mkxp-polyfill.cpp @@ -192,7 +192,7 @@ static void ctr_thread_launcher(void *data) { } #endif -#if defined(MKXPZ_NO_SEMAPHORE_H) && !defined(MKXPZ_NO_PTHREAD_H_MUTEX) +#if defined(MKXPZ_NO_SEMAPHORE_H) && defined(MKXPZ_NO_DISPATCH_DISPATCH_H) && !defined(MKXPZ_NO_PTHREAD_H_MUTEX) struct mkxp_sem_private { unsigned int value; mkxp_mutex_t mutex; @@ -380,6 +380,8 @@ extern "C" int mkxp_cond_wait(mkxp_cond_t *cond, mkxp_mutex_t *mutex) { extern "C" int mkxp_sem_init(mkxp_sem_t *sem, unsigned int value) { #ifndef MKXPZ_NO_SEMAPHORE_H return sem_init(sem, 0, value); +#elif !defined(MKXPZ_NO_DISPATCH_DISPATCH_H) + return (*sem = dispatch_semaphore_create(value)) == nullptr ? -1 : 0; #elif !defined(MKXPZ_NO_PTHREAD_H_MUTEX) *sem = (void *)new mkxp_sem_private; int mutex_init_result = mkxp_mutex_init(&((struct mkxp_sem_private *)*sem)->mutex, false); @@ -402,6 +404,9 @@ extern "C" int mkxp_sem_init(mkxp_sem_t *sem, unsigned int value) { extern "C" int mkxp_sem_destroy(mkxp_sem_t *sem) { #ifndef MKXPZ_NO_SEMAPHORE_H return sem_destroy(sem); +#elif !defined(MKXPZ_NO_DISPATCH_DISPATCH_H) + dispatch_release(*sem); + return 0; #elif !defined(MKXPZ_NO_PTHREAD_H_MUTEX) mkxp_cond_destroy(&((struct mkxp_sem_private *)*sem)->cond); mkxp_mutex_destroy(&((struct mkxp_sem_private *)*sem)->mutex); @@ -415,6 +420,9 @@ extern "C" int mkxp_sem_destroy(mkxp_sem_t *sem) { extern "C" int mkxp_sem_post(mkxp_sem_t *sem) { #ifndef MKXPZ_NO_SEMAPHORE_H return sem_post(sem); +#elif !defined(MKXPZ_NO_DISPATCH_DISPATCH_H) + dispatch_semaphore_signal(*sem); + return 0; #elif !defined(MKXPZ_NO_PTHREAD_H_MUTEX) while (mkxp_mutex_lock(&((struct mkxp_sem_private *)*sem)->mutex)) {} ++((struct mkxp_sem_private *)*sem)->value; @@ -430,6 +438,8 @@ extern "C" int mkxp_sem_post(mkxp_sem_t *sem) { extern "C" int mkxp_sem_wait(mkxp_sem_t *sem) { #ifndef MKXPZ_NO_SEMAPHORE_H return sem_wait(sem); +#elif !defined(MKXPZ_NO_DISPATCH_DISPATCH_H) + return dispatch_semaphore_wait(*sem, DISPATCH_TIME_FOREVER); #elif !defined(MKXPZ_NO_PTHREAD_H_MUTEX) while (mkxp_mutex_lock(&((struct mkxp_sem_private *)*sem)->mutex)) {} for (;;) { diff --git a/src/mkxp-polyfill.h b/src/mkxp-polyfill.h index f0063f9d..832b7b6e 100644 --- a/src/mkxp-polyfill.h +++ b/src/mkxp-polyfill.h @@ -30,6 +30,10 @@ #include #include +#if defined(__APPLE__) && !defined(MKXPZ_NO_SEMAPHORE_H) +# define MKXPZ_NO_SEMAPHORE_H +#endif + #if !defined(MKXPZ_NO_PTHREAD_H_MUTEX) || !defined(MKXPZ_NO_PTHREAD_H_THREAD) # include #endif @@ -38,6 +42,10 @@ # include #endif +#ifndef MKXPZ_NO_DISPATCH_DISPATCH_H +# include +#endif + #if !defined(__cplusplus) || defined(MKXPZ_NO_EXCEPTIONS) # define MKXPZ_THROW(...) do { fprintf(stderr, "Exception thrown: %s\n", (__VA_ARGS__).what()); fflush(stderr); abort(); } while (0) # define MKXPZ_RETHROW do { } while (0) @@ -76,6 +84,8 @@ typedef bool mkxp_cond_t; #ifndef MKXPZ_NO_SEMAPHORE_H typedef sem_t mkxp_sem_t; +#elif !defined(MKXPZ_NO_DISPATCH_DISPATCH_H) +typedef dispatch_semaphore_t mkxp_sem_t; #elif !defined(MKXPZ_NO_PTHREAD_H_MUTEX) typedef void *mkxp_sem_t; #else