#include "os/internal.h"
#include <mach/mach_init.h>
#include <mach/semaphore.h>
#include <mach/task.h>
#include <mach/thread_switch.h>
#define OS_VERIFY_MIG(x, msg) do { \
if (unlikely((x) == MIG_REPLY_MISMATCH)) { \
__LIBPLATFORM_CLIENT_CRASH__(x, msg); \
} \
} while (0)
#define OS_SEMAPHORE_VERIFY_KR(x, msg) do { \
if (unlikely(x)) { \
__LIBPLATFORM_CLIENT_CRASH__(x, msg); \
} \
} while (0)
os_semaphore_t
_os_semaphore_create(void)
{
semaphore_t s4;
kern_return_t kr;
kr = semaphore_create(mach_task_self(), &s4, SYNC_POLICY_FIFO, 0);
OS_VERIFY_MIG(kr, "Allocating semaphore failed with MIG_REPLY_MISMATCH");
OS_SEMAPHORE_VERIFY_KR(kr, "Creating semaphore failed, possible port leak");
return (os_semaphore_t)s4;
}
void
_os_semaphore_dispose(os_semaphore_t sema)
{
semaphore_t s4 = (semaphore_t)sema;
kern_return_t kr = semaphore_destroy(mach_task_self(), s4);
OS_SEMAPHORE_VERIFY_KR(kr, "Destroying semaphore failed");
}
void
_os_semaphore_signal(os_semaphore_t sema)
{
semaphore_t s4 = (semaphore_t)sema;
kern_return_t kr = semaphore_signal(s4);
OS_SEMAPHORE_VERIFY_KR(kr, "Signaling semaphore failed");
}
void
_os_semaphore_wait(os_semaphore_t sema)
{
semaphore_t s4 = (semaphore_t)sema;
kern_return_t kr;
do {
kr = semaphore_wait(s4);
} while (unlikely(kr == KERN_ABORTED));
OS_SEMAPHORE_VERIFY_KR(kr, "Waiting on semaphore failed");
}