From f93074a43019927a6aefc607bcd77172f5a03e08 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Sat, 23 Apr 2016 00:26:46 -0700 Subject: [PATCH] Add unnamed semaphore support on Mac OS sem_init() is not functional on Mac OS. Use the Grand Central Dispatch implementation. Make libscp_lock.c use semaphores through the thread_calls wrapper. --- common/thread_calls.c | 15 +++++++++++++++ sesman/libscp/libscp_lock.c | 22 +++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/common/thread_calls.c b/common/thread_calls.c index a68e902a..d828b353 100644 --- a/common/thread_calls.c +++ b/common/thread_calls.c @@ -20,6 +20,10 @@ #if defined(_WIN32) #include +#elif defined(__APPLE__) +#include +#include +#include #else #include #include @@ -159,6 +163,9 @@ tc_sem_create(int init_count) sem = CreateSemaphore(0, init_count, init_count + 10, 0); return (tbus)sem; +#elif defined(__APPLE__) + dispatch_semaphore_t sem = dispatch_semaphore_create(init_count); + return (tbus)sem; #else sem_t *sem = (sem_t *)NULL; @@ -174,6 +181,8 @@ tc_sem_delete(tbus sem) { #if defined(_WIN32) CloseHandle((HANDLE)sem); +#elif defined(__APPLE__) + dispatch_release((dispatch_semaphore_t)sem); #else sem_t *lsem; @@ -190,6 +199,9 @@ tc_sem_dec(tbus sem) #if defined(_WIN32) WaitForSingleObject((HANDLE)sem, INFINITE); return 0; +#elif defined(__APPLE__) + dispatch_semaphore_wait((dispatch_semaphore_t)sem, DISPATCH_TIME_FOREVER); + return 0; #else sem_wait((sem_t *)sem); return 0; @@ -203,6 +215,9 @@ tc_sem_inc(tbus sem) #if defined(_WIN32) ReleaseSemaphore((HANDLE)sem, 1, 0); return 0; +#elif defined(__APPLE__) + dispatch_semaphore_signal((dispatch_semaphore_t)sem); + return 0; #else sem_post((sem_t *)sem); return 0; diff --git a/sesman/libscp/libscp_lock.c b/sesman/libscp/libscp_lock.c index bd3ff771..848c1966 100644 --- a/sesman/libscp/libscp_lock.c +++ b/sesman/libscp/libscp_lock.c @@ -20,14 +20,14 @@ */ #include "libscp_lock.h" +#include "thread_calls.h" -#include #include pthread_mutex_t lock_fork; /* this lock protects the counters */ 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 */ -sem_t lock_fork_wait; /* semaphore on which the suspended process wait on */ +tbus lock_fork_req; /* semaphore on which the process that are going to fork suspend 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_blockers_count; /* threads thar are blocking fork */ int lock_fork_waiting_count; /* threads suspended until the fork finishes */ @@ -38,8 +38,8 @@ scp_lock_init(void) /* initializing fork lock */ pthread_mutexattr_init(&lock_fork_attr); pthread_mutex_init(&lock_fork, &lock_fork_attr); - sem_init(&lock_fork_req, 0, 0); - sem_init(&lock_fork_wait, 0, 0); + lock_fork_req = tc_sem_create(0); + lock_fork_wait = tc_sem_create(0); /* here we don't use locking because lock_init() should be called BEFORE */ /* any thread is created */ @@ -58,14 +58,14 @@ scp_lock_fork_request(void) if (lock_fork_blockers_count == 0) { /* 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++; pthread_mutex_unlock(&lock_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 (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--) { /* waking up the other processes */ - sem_post(&lock_fork_wait); + tc_sem_inc(lock_fork_wait); } pthread_mutex_unlock(&lock_fork); @@ -107,7 +107,7 @@ scp_lock_fork_critical_section_end(int blocking) /* then we let him go */ 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); @@ -129,7 +129,7 @@ scp_lock_fork_critical_section_start(void) pthread_mutex_unlock(&lock_fork); /* we wait until the fork finishes */ - sem_wait(&lock_fork_wait); + tc_sem_dec(lock_fork_wait); } else