From d94ee64363b07bc73213aa87223c5ad388c4ee26 Mon Sep 17 00:00:00 2001 From: Bill Lash Date: Mon, 24 Jun 2019 21:31:56 -0500 Subject: [PATCH] Make a try at MACOS unnamed semaphores --- Makefile | 2 +- src/curses/ux_audio.c | 28 ++++++------- src/curses/ux_input.c | 6 +-- src/curses/ux_sema.h | 91 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 src/curses/ux_sema.h diff --git a/Makefile b/Makefile index 436a1b7..8c4de6a 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,7 @@ CURSES ?= ncursesw # you need to define _XOPEN_SOURCE_EXTENDED ifdef MACOS CURSES = curses - CFLAGS += -D_XOPEN_SOURCE_EXTENDED + CFLAGS += -D_XOPEN_SOURCE_EXTENDED -DMACOS endif # Uncomment this if you want to disable the compilation of Blorb support. diff --git a/src/curses/ux_audio.c b/src/curses/ux_audio.c index 95640a3..2739387 100644 --- a/src/curses/ux_audio.c +++ b/src/curses/ux_audio.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include //pread @@ -39,11 +38,12 @@ #include #endif +#include "ux_sema.h" #include "ux_frotz.h" #include "ux_audio.h" f_setup_t f_setup; -sem_t sound_done; /* 1 if the sound is done */ +ux_sem_t sound_done; /* 1 if the sound is done */ #ifndef NO_SOUND @@ -176,8 +176,8 @@ typedef struct { sound_state_t voices[NUM_VOICES]; /* Max concurrent sound effects/music*/ /*Event (one is process per frame of audio)*/ - sem_t ev_free; /*1 if an event can be submitted*/ - sem_t ev_pending; /*1 if there's an event ready to be processed*/ + ux_sem_t ev_free; /*1 if an event can be submitted*/ + ux_sem_t ev_pending; /*1 if there's an event ready to be processed*/ sound_event_t event; } sound_engine_t; @@ -576,12 +576,12 @@ process_engine(sound_engine_t *e) { int i; /*Handle event*/ - if(sem_trywait(&e->ev_pending) == 0) { + if(ux_sem_trywait(&e->ev_pending) == 0) { if(e->event.type == EVENT_START_STREAM) sound_enqueue_real(e,e->event.e); else if(e->event.type == EVENT_STOP_STREAM) sound_stop_id_real(e,e->event.i); - sem_post(&e->ev_free); + ux_sem_post(&e->ev_free); } /*Start out with an empty buffer*/ @@ -605,7 +605,7 @@ process_engine(sound_engine_t *e) sound->cleanup(sound); free(sound); e->streams[i] = NULL; - sem_post(&sound_done); + ux_sem_post(&sound_done); } } } @@ -696,10 +696,10 @@ static sound_stream_t *load_aiff(FILE *fp, long startpos, long length, int id, f static void sound_stop_id(int id) { - sem_wait(&frotz_audio.ev_free); + ux_sem_wait(&frotz_audio.ev_free); frotz_audio.event.type = EVENT_STOP_STREAM; frotz_audio.event.i = id; - sem_post(&frotz_audio.ev_pending); + ux_sem_post(&frotz_audio.ev_pending); } static void @@ -720,10 +720,10 @@ sound_stop_id_real(sound_engine_t *e, int id) static void sound_enqueue(sound_stream_t *s) { - sem_wait(&frotz_audio.ev_free); + ux_sem_wait(&frotz_audio.ev_free); frotz_audio.event.type = EVENT_START_STREAM; frotz_audio.event.e = s; - sem_post(&frotz_audio.ev_pending); + ux_sem_post(&frotz_audio.ev_pending); } static void @@ -794,9 +794,9 @@ os_init_sound(void) frotz_audio.voices[i].active = 0; /*No events registered on startup*/ - sem_init(&frotz_audio.ev_free, 0, 1); - sem_init(&frotz_audio.ev_pending, 0, 0); - sem_init(&sound_done, 0, 0); + ux_sem_init(&frotz_audio.ev_free, 0, 1); + ux_sem_init(&frotz_audio.ev_pending, 0, 0); + ux_sem_init(&sound_done, 0, 0); frotz_audio.event.type = 0; /*Start audio thread*/ diff --git a/src/curses/ux_input.c b/src/curses/ux_input.c index ba0262f..45d7e6b 100644 --- a/src/curses/ux_input.c +++ b/src/curses/ux_input.c @@ -40,8 +40,8 @@ #endif #ifndef NO_SOUND -#include -sem_t sound_done; +#include "ux_sema.h" +ux_sem_t sound_done; #endif #include "ux_frotz.h" @@ -152,7 +152,7 @@ void os_tick() } #ifndef NO_SOUND - if (sem_trywait(&sound_done) == 0) + if (ux_sem_trywait(&sound_done) == 0) end_of_sound(); #endif } diff --git a/src/curses/ux_sema.h b/src/curses/ux_sema.h new file mode 100644 index 0000000..7a01cd4 --- /dev/null +++ b/src/curses/ux_sema.h @@ -0,0 +1,91 @@ +/* + * ux_sema.h - semaphore abstraction for frotz + * + * This file is part of Frotz. + * + * Frotz is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Frotz is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Or visit http://www.fsf.org/ + * + * This file and only this file is dual licensed under the MIT license. + * + */ + +/* + * For anything other than MAC OS X, this is a simple wrapper for unnamed + * POSIX Semaphores. For MAC OS X use the Grand Central Dispatch as suggested + * at https://stackoverflow.com/questions/27736618/why-are-sem-init-sem-getvalue-sem-destroy-deprecated-on-mac-os-x-and-w + */ + +#ifdef MACOS +#include +struct ux_sema { + dispatch_semaphore_t dsem; +}; +typedef struct ux_sema ux_sem_t; + +/* + * Note that the current implementation does not check return codes + * so use void to make things simpler on the MAC side + */ +static inline void ux_sem_init(ux_sem_t *sem, int pshared, unsigned int value) +{ + dispatch_semaphore_t *sema = &sem->dsem; + (void) pshared; + + *sema = dispatch_semaphore_create(value); +} + +static inline void ux_sem_post(ux_sem_t *sem) +{ + dispatch_semaphore_signal(sem->dsem); +} + +static inline void ux_sem_wait(ux_sem_t *sem) +{ + dispatch_semaphore_wait(sem->dsem, DISPATCH_TIME_FOREVER); +} + +static inline int ux_sem_trywait(ux_sem_t *sem) +{ + return (int) dispatch_semaphore_wait(sem->dsem, DISPATCH_TIME_NOW); +} +#else +#include +typedef sem_t ux_sem_t; + +/* + * Note that the current implementation does not check return codes + * so use void to make things simpler on the MAC side + */ +static inline void ux_sem_init(ux_sem_t *sem, int pshared, unsigned int value) +{ + (void) sem_init(sem, pshared, value); +} + +static inline void ux_sem_post(ux_sem_t *sem) +{ + (void) sem_post(sem); +} + +static inline void ux_sem_wait(ux_sem_t *sem) +{ + (void) sem_wait(sem); +} + +static inline int ux_sem_trywait(ux_sem_t *sem) +{ + return sem_trywait(sem); +} +#endif -- 2.34.1