summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-01-10 01:46:16 +0000
committerDavid Robillard <d@drobilla.net>2011-01-10 01:46:16 +0000
commit378cfbf96708625e98280c4145d1dbdd9bb009b8 (patch)
tree7deb1334a7b48f290cde76a8cd91dfce3f20c0c2
parent00aae38aecaccc9e245a3da85f619cf4503c1855 (diff)
downloadraul-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.in2
-rw-r--r--raul/Semaphore.hpp67
-rw-r--r--wscript17
3 files changed, 73 insertions, 13 deletions
diff --git a/raul.pc.in b/raul.pc.in
index 316ed2c..db1293b 100644
--- a/raul.pc.in
+++ b/raul.pc.in
@@ -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
};
diff --git a/wscript b/wscript
index 44c7067..4b2318f 100644
--- a/wscript
+++ b/wscript
@@ -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)