#include "threading.h"


RT_DLLEXPORT rt_create_semaphore_result rtCreateSemaphore(int initial_value, int max_value) {
    rt_create_semaphore_result res;
    res.semaphore.cond = rtCreateConditionVar();
    if (!res.semaphore.cond) {
        res.ok = false;
        return res;
    }
    res.semaphore.counter = initial_value;
    res.semaphore.max     = max_value;
    res.ok                = true;
    return res;
}

RT_DLLEXPORT void rtDestroySemaphore(rt_semaphore *sem) {
    rtDestroyConditionVar(sem->cond);
    sem->cond    = NULL;
    sem->counter = 0;
    sem->max     = 0;
}

RT_DLLEXPORT void rtSignalSemaphore(rt_semaphore *sem) {
    rtLockConditionVar(sem->cond);
    RT_ASSERT(sem->counter < sem->max,
              "Tried to signal a semaphore that has reached its maximum value.");
    ++sem->counter;
    rtUnlockConditionVar(sem->cond, true);
}

RT_DLLEXPORT void rtWaitOnSemaphore(rt_semaphore *sem) {
    rtLockConditionVar(sem->cond);
    while (sem->counter == 0) {
        rtWaitOnConditionVar(sem->cond);
    }
    --sem->counter;
    rtUnlockConditionVar(sem->cond, false);
}