From 7ab0a7aff262ba265ac5e152d4b1ec34d8b740ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arttu=20Yl=C3=A4-Outinen?= Date: Wed, 12 Apr 2017 02:55:01 -0700 Subject: [PATCH] Fix semaphores on Mac POSIX semaphores are deprecated on Mac. This commit replaces POSIX semaphores by Grand Central Dispatch semaphores when building on Mac. --- src/encmain.c | 33 ++++++++++++++-------------- src/threads.h | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 17 deletions(-) diff --git a/src/encmain.c b/src/encmain.c index ace0c7ba..6ef66e03 100644 --- a/src/encmain.c +++ b/src/encmain.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -126,8 +125,8 @@ static void compute_psnr(const kvz_picture *const src, typedef struct { // Semaphores for synchronization. - sem_t* available_input_slots; - sem_t* filled_input_slots; + kvz_sem_t* available_input_slots; + kvz_sem_t* filled_input_slots; // Parameters passed from main thread to input thread. FILE* input; @@ -240,24 +239,24 @@ static void* input_read_thread(void* in_args) } // Wait until main thread is ready to receive the next frame. - sem_wait(args->available_input_slots); + kvz_sem_wait(args->available_input_slots); args->img_in = frame_in; args->retval = retval; // Unlock main_thread_mutex to notify main thread that the new img_in // and retval have been placed to args. - sem_post(args->filled_input_slots); + kvz_sem_post(args->filled_input_slots); frame_in = NULL; } done: // Wait until main thread is ready to receive the next frame. - sem_wait(args->available_input_slots); + kvz_sem_wait(args->available_input_slots); args->img_in = NULL; args->retval = retval; // Unlock main_thread_mutex to notify main thread that the new img_in // and retval have been placed to args. - sem_post(args->filled_input_slots); + kvz_sem_post(args->filled_input_slots); // Do some cleaning up. args->api->picture_free(frame_in); @@ -343,8 +342,8 @@ int main(int argc, char *argv[]) // if the input has ended) in input_handler_args.img_in placed by the // input reader thread. (0 = no new image, 1 = one new image) // - sem_t *available_input_slots = NULL; - sem_t *filled_input_slots = NULL; + kvz_sem_t *available_input_slots = NULL; + kvz_sem_t *filled_input_slots = NULL; #ifdef _WIN32 // Stderr needs to be text mode to convert \n to \r\n in Windows. @@ -434,10 +433,10 @@ int main(int argc, char *argv[]) pthread_t input_thread; - available_input_slots = calloc(1, sizeof(sem_t)); - filled_input_slots = calloc(1, sizeof(sem_t)); - sem_init(available_input_slots, 0, 0); - sem_init(filled_input_slots, 0, 0); + available_input_slots = calloc(1, sizeof(kvz_sem_t)); + filled_input_slots = calloc(1, sizeof(kvz_sem_t)); + kvz_sem_init(available_input_slots, 0); + kvz_sem_init(filled_input_slots, 0); // Give arguments via struct to the input thread input_handler_args in_args = { @@ -469,10 +468,10 @@ int main(int argc, char *argv[]) if (in_args.retval == RETVAL_RUNNING) { // Increase available_input_slots so that the input thread can // write the new img_in and retval to in_args. - sem_post(available_input_slots); + kvz_sem_post(available_input_slots); // Wait until the input thread has updated in_args and then // decrease filled_input_slots. - sem_wait(filled_input_slots); + kvz_sem_wait(filled_input_slots); cur_in_img = in_args.img_in; in_args.img_in = NULL; @@ -606,8 +605,8 @@ exit_failure: done: // destroy semaphores - if (available_input_slots) sem_destroy(available_input_slots); - if (filled_input_slots) sem_destroy(filled_input_slots); + if (available_input_slots) kvz_sem_destroy(available_input_slots); + if (filled_input_slots) kvz_sem_destroy(filled_input_slots); FREE_POINTER(available_input_slots); FREE_POINTER(filled_input_slots); diff --git a/src/threads.h b/src/threads.h index c34fd4a6..074fd589 100644 --- a/src/threads.h +++ b/src/threads.h @@ -76,6 +76,66 @@ #endif //__GNUC__ +#ifdef __APPLE__ +// POSIX semaphores are deprecated on Mac so we use Grand Central Dispatch +// semaphores instead. +#include +typedef dispatch_semaphore_t kvz_sem_t; + +static INLINE void kvz_sem_init(kvz_sem_t *sem, int value) +{ + assert(value >= 0); + *sem = dispatch_semaphore_create(value); +} + +static INLINE void kvz_sem_wait(kvz_sem_t *sem) +{ + dispatch_semaphore_wait(*sem, DISPATCH_TIME_FOREVER); +} + +static INLINE void kvz_sem_post(kvz_sem_t *sem) +{ + dispatch_semaphore_signal(*sem); +} + + +static INLINE void kvz_sem_destroy(kvz_sem_t *sem) +{ + // Do nothing for GCD semaphores. +} + +#else +// Use POSIX semaphores. +#include + +typedef sem_t kvz_sem_t; + +static INLINE void kvz_sem_init(kvz_sem_t *sem, int value) +{ + assert(value >= 0); + // Pthreads-w32 does not support process-shared semaphores, so pshared + // must always be zero. + int pshared = 0; + sem_init(sem, pshared, value); +} + +static INLINE void kvz_sem_wait(kvz_sem_t *sem) +{ + sem_wait(sem); +} + +static INLINE void kvz_sem_post(kvz_sem_t *sem) +{ + sem_post(sem); +} + +static INLINE void kvz_sem_destroy(kvz_sem_t *sem) +{ + sem_destroy(sem); +} + +#endif + #undef E9 #undef E3