Merge pull request #366 from proski/macos-sem

Add unnamed semaphore support on Mac OS
ulab-next-nosound
jsorg71 9 years ago
commit b0e1e21305

@ -20,6 +20,10 @@
#if defined(_WIN32) #if defined(_WIN32)
#include <windows.h> #include <windows.h>
#elif defined(__APPLE__)
#include <pthread.h>
#include <dispatch/dispatch.h>
#include <dispatch/time.h>
#else #else
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
@ -159,6 +163,9 @@ tc_sem_create(int init_count)
sem = CreateSemaphore(0, init_count, init_count + 10, 0); sem = CreateSemaphore(0, init_count, init_count + 10, 0);
return (tbus)sem; return (tbus)sem;
#elif defined(__APPLE__)
dispatch_semaphore_t sem = dispatch_semaphore_create(init_count);
return (tbus)sem;
#else #else
sem_t *sem = (sem_t *)NULL; sem_t *sem = (sem_t *)NULL;
@ -174,6 +181,8 @@ tc_sem_delete(tbus sem)
{ {
#if defined(_WIN32) #if defined(_WIN32)
CloseHandle((HANDLE)sem); CloseHandle((HANDLE)sem);
#elif defined(__APPLE__)
dispatch_release((dispatch_semaphore_t)sem);
#else #else
sem_t *lsem; sem_t *lsem;
@ -190,6 +199,9 @@ tc_sem_dec(tbus sem)
#if defined(_WIN32) #if defined(_WIN32)
WaitForSingleObject((HANDLE)sem, INFINITE); WaitForSingleObject((HANDLE)sem, INFINITE);
return 0; return 0;
#elif defined(__APPLE__)
dispatch_semaphore_wait((dispatch_semaphore_t)sem, DISPATCH_TIME_FOREVER);
return 0;
#else #else
sem_wait((sem_t *)sem); sem_wait((sem_t *)sem);
return 0; return 0;
@ -203,6 +215,9 @@ tc_sem_inc(tbus sem)
#if defined(_WIN32) #if defined(_WIN32)
ReleaseSemaphore((HANDLE)sem, 1, 0); ReleaseSemaphore((HANDLE)sem, 1, 0);
return 0; return 0;
#elif defined(__APPLE__)
dispatch_semaphore_signal((dispatch_semaphore_t)sem);
return 0;
#else #else
sem_post((sem_t *)sem); sem_post((sem_t *)sem);
return 0; return 0;

@ -20,14 +20,14 @@
*/ */
#include "libscp_lock.h" #include "libscp_lock.h"
#include "thread_calls.h"
#include <semaphore.h>
#include <pthread.h> #include <pthread.h>
pthread_mutex_t lock_fork; /* this lock protects the counters */ pthread_mutex_t lock_fork; /* this lock protects the counters */
pthread_mutexattr_t lock_fork_attr; /* mutex attributes */ pthread_mutexattr_t lock_fork_attr; /* mutex attributes */
sem_t lock_fork_req; /* semaphore on which the process that are going to fork suspend on */ tbus lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
sem_t lock_fork_wait; /* semaphore on which the suspended process wait on */ tbus lock_fork_wait; /* semaphore on which the suspended process wait on */
int lock_fork_forkers_count; /* threads that want to fork */ int lock_fork_forkers_count; /* threads that want to fork */
int lock_fork_blockers_count; /* threads thar are blocking fork */ int lock_fork_blockers_count; /* threads thar are blocking fork */
int lock_fork_waiting_count; /* threads suspended until the fork finishes */ int lock_fork_waiting_count; /* threads suspended until the fork finishes */
@ -38,8 +38,8 @@ scp_lock_init(void)
/* initializing fork lock */ /* initializing fork lock */
pthread_mutexattr_init(&lock_fork_attr); pthread_mutexattr_init(&lock_fork_attr);
pthread_mutex_init(&lock_fork, &lock_fork_attr); pthread_mutex_init(&lock_fork, &lock_fork_attr);
sem_init(&lock_fork_req, 0, 0); lock_fork_req = tc_sem_create(0);
sem_init(&lock_fork_wait, 0, 0); lock_fork_wait = tc_sem_create(0);
/* here we don't use locking because lock_init() should be called BEFORE */ /* here we don't use locking because lock_init() should be called BEFORE */
/* any thread is created */ /* any thread is created */
@ -58,14 +58,14 @@ scp_lock_fork_request(void)
if (lock_fork_blockers_count == 0) if (lock_fork_blockers_count == 0)
{ {
/* if no one is blocking fork(), then we're allowed to fork */ /* if no one is blocking fork(), then we're allowed to fork */
sem_post(&lock_fork_req); tc_sem_inc(lock_fork_req);
} }
lock_fork_forkers_count++; lock_fork_forkers_count++;
pthread_mutex_unlock(&lock_fork); pthread_mutex_unlock(&lock_fork);
/* we wait to be allowed to fork() */ /* we wait to be allowed to fork() */
sem_wait(&lock_fork_req); tc_sem_dec(lock_fork_req);
} }
/******************************************************************************/ /******************************************************************************/
@ -78,13 +78,13 @@ scp_lock_fork_release(void)
/* if there's someone else that want to fork, we let him fork() */ /* if there's someone else that want to fork, we let him fork() */
if (lock_fork_forkers_count > 0) if (lock_fork_forkers_count > 0)
{ {
sem_post(&lock_fork_req); tc_sem_inc(lock_fork_req);
} }
for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--) for (; lock_fork_waiting_count > 0; lock_fork_waiting_count--)
{ {
/* waking up the other processes */ /* waking up the other processes */
sem_post(&lock_fork_wait); tc_sem_inc(lock_fork_wait);
} }
pthread_mutex_unlock(&lock_fork); pthread_mutex_unlock(&lock_fork);
@ -107,7 +107,7 @@ scp_lock_fork_critical_section_end(int blocking)
/* then we let him go */ /* then we let him go */
if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count > 0)) if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count > 0))
{ {
sem_post(&lock_fork_req); tc_sem_inc(lock_fork_req);
} }
pthread_mutex_unlock(&lock_fork); pthread_mutex_unlock(&lock_fork);
@ -129,7 +129,7 @@ scp_lock_fork_critical_section_start(void)
pthread_mutex_unlock(&lock_fork); pthread_mutex_unlock(&lock_fork);
/* we wait until the fork finishes */ /* we wait until the fork finishes */
sem_wait(&lock_fork_wait); tc_sem_dec(lock_fork_wait);
} }
else else

Loading…
Cancel
Save