Skip to content

Commit

Permalink
Fix local semaphore under macOS, optimize linux futexes
Browse files Browse the repository at this point in the history
  • Loading branch information
falkTX committed Sep 15, 2018
1 parent bff24bc commit 8b9db39
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 12 deletions.
2 changes: 1 addition & 1 deletion source/backend/engine/CarlaEngineInternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ EngineNextAction::EngineNextAction() noexcept
mutex(),
needsPost(false),
postDone(false),
sem(carla_sem_create()) {}
sem(carla_sem_create(false)) {}

EngineNextAction::~EngineNextAction() noexcept
{
Expand Down
2 changes: 1 addition & 1 deletion source/jackbridge/JackBridge2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bool jackbridge_sem_init(void* sem) noexcept
CARLA_SAFE_ASSERT_RETURN(sem != nullptr, false);

#ifndef JACKBRIDGE_DUMMY
return carla_sem_create2(*(carla_sem_t*)sem);
return carla_sem_create2(*(carla_sem_t*)sem, true);
#endif
}

Expand Down
27 changes: 17 additions & 10 deletions source/utils/CarlaSemUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct carla_sem_t { char bootname[32]; semaphore_t sem; semaphore_t sem2; };
# include <syscall.h>
# include <sys/time.h>
# include <linux/futex.h>
struct carla_sem_t { int count; };
struct carla_sem_t { int count; bool external; };
#else
# include <cerrno>
# include <semaphore.h>
Expand All @@ -54,7 +54,7 @@ struct carla_sem_t { sem_t sem; };
* Create a new semaphore, pre-allocated version.
*/
static inline
bool carla_sem_create2(carla_sem_t& sem) noexcept
bool carla_sem_create2(carla_sem_t& sem, const bool externalIPC) noexcept
{
carla_zeroStruct(sem);
#if defined(CARLA_OS_WIN)
Expand All @@ -63,41 +63,48 @@ bool carla_sem_create2(carla_sem_t& sem) noexcept
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;

sem.handle = ::CreateSemaphore(&sa, 0, 1, nullptr);
sem.handle = ::CreateSemaphoreA(externalIPC ? &sa : nullptr, 0, 1, nullptr);

return (sem.handle != INVALID_HANDLE_VALUE);
#elif defined(CARLA_OS_MAC)
mach_port_t bootport;
const mach_port_t task = ::mach_task_self();

mach_port_t bootport;
CARLA_SAFE_ASSERT_RETURN(task_get_bootstrap_port(task, &bootport) == KERN_SUCCESS, false);
if (externalIPC) {
CARLA_SAFE_ASSERT_RETURN(task_get_bootstrap_port(task, &bootport) == KERN_SUCCESS, false);
}
CARLA_SAFE_ASSERT_RETURN(::semaphore_create(task, &sem.sem, SYNC_POLICY_FIFO, 0) == KERN_SUCCESS, false);

if (! externalIPC)
return true;

static int bootcounter = 0;
std::snprintf(sem.bootname, 31, "crlsm_%i_%i_%p", ++bootcounter, ::getpid(), &sem);
sem.bootname[31] = '\0';

if (::bootstrap_register(bootport, sem.bootname, sem.sem) == KERN_SUCCESS)
return true;

sem.bootname[0] = '\0';
::semaphore_destroy(task, sem.sem);
return false;
#elif defined(CARLA_USE_FUTEXES)
sem.external = externalIPC;
return true;
#else
return (::sem_init(&sem.sem, 1, 0) == 0);
return (::sem_init(&sem.sem, externalIPC, 0) == 0);
#endif
}

/*
* Create a new semaphore.
*/
static inline
carla_sem_t* carla_sem_create() noexcept
carla_sem_t* carla_sem_create(const bool externalIPC) noexcept
{
if (carla_sem_t* const sem = (carla_sem_t*)std::malloc(sizeof(carla_sem_t)))
{
if (carla_sem_create2(*sem))
if (carla_sem_create2(*sem, externalIPC))
return sem;

std::free(sem);
Expand Down Expand Up @@ -173,7 +180,7 @@ void carla_sem_post(carla_sem_t& sem, const bool server = true) noexcept
#elif defined(CARLA_USE_FUTEXES)
const bool unlocked = __sync_bool_compare_and_swap(&sem.count, 0, 1);
CARLA_SAFE_ASSERT_RETURN(unlocked,);
::syscall(__NR_futex, &sem.count, FUTEX_WAKE, 1, nullptr, nullptr, 0);
::syscall(__NR_futex, &sem.count, sem.external ? FUTEX_WAKE : FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr, 0);
#else
::sem_post(&sem.sem);
#endif
Expand Down Expand Up @@ -209,7 +216,7 @@ bool carla_sem_timedwait(carla_sem_t& sem, const uint msecs, const bool server =
if (__sync_bool_compare_and_swap(&sem.count, 1, 0))
return true;

if (::syscall(__NR_futex, &sem.count, FUTEX_WAIT, 0, &timeout, nullptr, 0) != 0)
if (::syscall(__NR_futex, &sem.count, sem.external ? FUTEX_WAIT : FUTEX_WAIT_PRIVATE, 0, &timeout, nullptr, 0) != 0)
if (errno != EAGAIN && errno != EINTR)
return false;
}
Expand Down

0 comments on commit 8b9db39

Please sign in to comment.