diff options
author | David Robillard <d@drobilla.net> | 2011-01-10 01:46:16 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2011-01-10 01:46:16 +0000 |
commit | 378cfbf96708625e98280c4145d1dbdd9bb009b8 (patch) | |
tree | 7deb1334a7b48f290cde76a8cd91dfce3f20c0c2 | |
parent | 00aae38aecaccc9e245a3da85f619cf4503c1855 (diff) | |
download | raul-378cfbf96708625e98280c4145d1dbdd9bb009b8.tar.gz raul-378cfbf96708625e98280c4145d1dbdd9bb009b8.tar.bz2 raul-378cfbf96708625e98280c4145d1dbdd9bb009b8.zip |
Working semaphore implementation for OSX.
git-svn-id: http://svn.drobilla.net/lad/trunk/raul@2809 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | raul.pc.in | 2 | ||||
-rw-r--r-- | raul/Semaphore.hpp | 67 | ||||
-rw-r--r-- | wscript | 17 |
3 files changed, 73 insertions, 13 deletions
@@ -6,5 +6,5 @@ includedir=@includedir@ Name: raul Version: @RAUL_VERSION@ Description: A C++ convenience library for realtime audio applications -Libs: -L${libdir} -lraul @GLIB_LIBS@ @GTHREAD_LIBS@ +Libs: -L${libdir} -lraul @GLIB_LIBS@ @GTHREAD_LIBS@ @RAUL_PC_LIBS@ Cflags: -I${includedir} @GLIB_CFLAGS@ @GTHREAD_CFLAGS@ diff --git a/raul/Semaphore.hpp b/raul/Semaphore.hpp index 6b7d0d7..c7b29ef 100644 --- a/raul/Semaphore.hpp +++ b/raul/Semaphore.hpp @@ -18,30 +18,56 @@ #ifndef RAUL_SEMAPHORE_HPP #define RAUL_SEMAPHORE_HPP +#ifdef __APPLE__ +#include <limits.h> +#include <CoreServices/CoreServices.h> +#else #include <semaphore.h> +#endif + #include <boost/utility.hpp> namespace Raul { -/** Trivial wrapper around POSIX semaphores (zero memory overhead). +/** Counting semaphore. * * \ingroup raul */ class Semaphore : boost::noncopyable { public: - inline Semaphore(unsigned int initial) { sem_init(&_sem, 0, initial); } + inline Semaphore(unsigned int initial) { + #ifdef __APPLE__ + MPCreateSemaphore(UINT_MAX, initial, &_sem); + #else + sem_init(&_sem, 0, initial); + #endif + } - inline ~Semaphore() { sem_destroy(&_sem); } + inline ~Semaphore() { + #ifdef __APPLE__ + MPDeleteSemaphore(_sem); + #else + sem_destroy(&_sem); + #endif + } inline void reset(unsigned int initial) { + #ifdef __APPLE__ + MPDeleteSemaphore(_sem); + MPCreateSemaphore(UINT_MAX, initial, &_sem); + #else sem_destroy(&_sem); sem_init(&_sem, 0, initial); + #endif } inline bool has_waiter() { int val; + #ifdef __APPLE__ + #else sem_getvalue(&_sem, &val); + #endif return (val <= 0); } @@ -49,16 +75,29 @@ public: * * Realtime safe. */ - inline void post() { sem_post(&_sem); } + inline void post() { + #ifdef __APPLE__ + MPSignalSemaphore(_sem); + #else + sem_post(&_sem); + #endif + } /** Wait until count is > 0, then decrement. * - * Note that sem_wait always returns 0 in practice. It returns nonzero - * when run in GDB, so the while is necessary to allow debugging. - * * Obviously not realtime safe. */ - inline void wait() { while (sem_wait(&_sem) != 0) {} } + inline void wait() { + #ifdef __APPLE__ + MPWaitOnSemaphore(_sem, kDurationForever); + #else + /* Note that sem_wait always returns 0 in practice, except in + gdb (at least), where it returns nonzero, so the while is + necessary (and is the correct/safe solution in any case). + */ + while (sem_wait(&_sem) != 0) {} + #endif + } /** Non-blocking version of wait(). * @@ -66,10 +105,20 @@ public: * * Realtime safe? */ - inline bool try_wait() { return (sem_trywait(&_sem) == 0); } + inline bool try_wait() { + #ifdef __APPLE__ + return MPWaitOnSemaphore(_sem, kDurationImmediate) == noErr; + #else + return (sem_trywait(&_sem) == 0); + #endif + } private: + #ifdef __APPLE__ + MPSemaphoreID _sem; + #else sem_t _sem; + #endif }; @@ -88,7 +88,10 @@ def build(bld): bld.install_files('${INCLUDEDIR}/raul', bld.path.ant_glob('raul/*.h')) # Pkgconfig file - autowaf.build_pc(bld, 'RAUL', RAUL_VERSION, 'GLIB GTHREAD') + dict = {} + if Options.platform == 'darwin': + dict = {'RAUL_PC_LIBS': '-framework CoreServices'} + autowaf.build_pc(bld, 'RAUL', RAUL_VERSION, 'GLIB GTHREAD', subst_dict=dict) lib_source = ''' src/Configuration.cpp @@ -101,6 +104,11 @@ def build(bld): src/log.cpp ''' + def set_link_flags(obj): + obj.linkflags = [] + if Options.platform == 'darwin': + obj.linkflags = ['-framework', 'CoreServices'] + # Library obj = bld(features = 'cxx cxxshlib') obj.export_includes = ['.'] @@ -111,7 +119,8 @@ def build(bld): obj.uselib = 'GLIB GTHREAD' obj.install_path = '${LIBDIR}' obj.vnum = RAUL_LIB_VERSION - + set_link_flags(obj) + if bld.env['BUILD_TESTS']: # Static library (for unit test code coverage) obj = bld(features = 'cxx cxxstlib') @@ -122,6 +131,7 @@ def build(bld): obj.uselib = 'GLIB GTHREAD' obj.install_path = '' obj.cxxflags = [ '-fprofile-arcs', '-ftest-coverage' ] + set_link_flags(obj) # Unit tests for i in tests.split(): @@ -130,10 +140,11 @@ def build(bld): obj.includes = ['.', './src'] obj.use = 'libraul_static' obj.uselib = 'GLIB GTHREAD' - obj.linkflags = '-lgcov' obj.target = i obj.install_path = '' obj.cxxflags = [ '-fprofile-arcs', '-ftest-coverage' ] + set_link_flags(obj) + obj.linkflags += ['-lgcov'] # Documentation autowaf.build_dox(bld, 'RAUL', RAUL_VERSION, top, out) |