/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the BSD 2-Clause license. Note that NO WARRANTY is provided.
 * See "LICENSE_BSD2.txt" for details.
 *
 * @TAG(DATA61_BSD)
 */

#pragma once

#include <autoconf.h>
#include <sel4/sel4.h>
#ifdef CONFIG_DEBUG_BUILD
#include <sel4debug/debug.h>
#endif
#include <vka/vka.h>
#include <vka/object.h>
#include <platsupport/sync/atomic.h>
#include <stdbool.h>

typedef struct {
    vka_object_t notification;
    volatile int waiters;
    volatile bool broadcasting;
} sync_cv_t;

/* Initialise an unmanaged condition variable
 * @param cv            A condition variable object to be initialised.
 * @param notification  A notification object to use for wake up.
 * @return              0 on success, an error code on failure. */
static inline int sync_cv_init(sync_cv_t *cv, seL4_CPtr notification)
{
    if (cv == NULL) {
        ZF_LOGE("Condition variable passed to sync_cv_init is NULL");
        return -1;
    }

#ifdef CONFIG_DEBUG_BUILD
    /* Check the cap actually is a notification. */
    assert(debug_cap_is_notification(notification));
#endif

    cv->notification.cptr = notification;
    cv->waiters = 0;
    cv->broadcasting = false;
    return 0;
}

/* Wait on a condition variable.
 * This assumes that you already hold the lock and will block until notified
 * by sync_cv_signal or sync_cv_broadcast. It returns once you hold the lock
 * again. Note that a spurious wake up is possible and the condition should
 * always be checked again after sync_cv_wait returns.
 * @param lock          The lock on the monitor.
 * @param cv            The condition variable to wait on.
 * @return              0 on success, an error code on failure. */
static inline int sync_cv_wait(sync_bin_sem_t *lock, sync_cv_t *cv)
{
    if (cv == NULL) {
        ZF_LOGE("Condition variable passed to sync_cv_wait is NULL");
        return -1;
    }

    /* Increment waiters count and release the lock */
    cv->waiters++;
    cv->broadcasting = false;
    int error = sync_bin_sem_post(lock);
    if (error != 0) {
        return error;
    }

    /* Wait to be notified */
    seL4_Wait(cv->notification.cptr, NULL);

    /* Reacquire the lock */
    error = sync_bin_sem_wait(lock);
    if (error != 0) {
        return error;
    }

    /* Wake up and decrement waiters count */
    cv->waiters--;

    /* Handle the case where a broadcast is ongoing */
    if (cv->broadcasting) {
        if (cv->waiters > 0) {
            /* Signal the next thread and continue */
            seL4_Signal(cv->notification.cptr);
        } else {
            /* This is the last thread, so stop broadcasting */
            cv->broadcasting = false;
        }
    }

    return 0;
}

/* Signal a condition variable.
 * This assumes that you hold the lock and notifies one waiter
 * @param cv            The condition variable to signal.
 * @return              0 on success, an error code on failure. */
static inline int sync_cv_signal(sync_cv_t *cv)
{
    if (cv == NULL) {
        ZF_LOGE("Condition variable passed to sync_cv_signal is NULL");
        return -1;
    }
    if (cv->waiters > 0) {
        seL4_Signal(cv->notification.cptr);
    }

    return 0;
}

/* Broadcast to a condition variable.
 * This assumes that you hold the lock and notifies all waiters
 * @param cv            The condition variable to broadcast to.
 * @return              0 on success, an error code on failure. */
static inline int sync_cv_broadcast(sync_cv_t *cv)
{
    if (cv == NULL) {
        ZF_LOGE("Condition variable passed to sync_cv_broadcast is NULL");
        return -1;
    }

    if (cv->waiters > 0) {
        cv->broadcasting = true;
        seL4_Signal(cv->notification.cptr);
    }

    return 0;
}

/* Broadcast to a condition variable and release the lock.
 * This function is useful in situations where the scheduler might wake up a
 * waiter immediately after a signal (i.e. if the broadcaster is lower priority).
 * For performance reasons it is useful to release the lock prior to signalling
 * the condition variable in this case.
 * @param cv            The condition variable to broadcast to.
 * @return              0 on success, an error code on failure. */
static inline int sync_cv_broadcast_release(sync_bin_sem_t *lock, sync_cv_t *cv)
{
    if (cv == NULL) {
        ZF_LOGE("Condition variable passed to sync_cv_broadcast_release is NULL");
        return -1;
    }

    if (cv->waiters > 0) {
        cv->broadcasting = true;

        int error = sync_bin_sem_post(lock);
        if (error != 0) {
            return error;
        }

        seL4_Signal(cv->notification.cptr);
        return 0;
    } else {
        return sync_bin_sem_post(lock);
    }
}

/* Initialise a managed condition variable.
 * @param vka           A VKA instance used to allocate the notification object.
 * @param cv            A condition variable object to initialise.
 * @return              0 on success, an error code on failure. */
static inline int sync_cv_new(vka_t *vka, sync_cv_t *cv)
{
    if (cv == NULL) {
        ZF_LOGE("Condition variable passed to sync_cv_new is NULL");
        return -1;
    }

    int error = vka_alloc_notification(vka, &(cv->notification));

    if (error != 0) {
        return error;
    } else {
        return sync_cv_init(cv, cv->notification.cptr);
    }
}

/* Destroy a managed condition variable.
 * Uses the passed vka instance to deallocate the notification object.
 * This function is not to be used on unmanaged condition variables.
 * @param vka           A VKA instance used to deallocate the notification object.
 * @param cv            A condition variable object initialised by sync_cv_new.
 * @return              0 on success, an error code on failure. */
static inline int sync_cv_destroy(vka_t *vka, sync_cv_t *cv)
{
    if (cv == NULL) {
        ZF_LOGE("Condition variable passed to sync_cv_destroy is NULL");
        return -1;
    }
    vka_free_object(vka, &(cv->notification));
    return 0;
}
