/*
 * 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)
 */

#include <autoconf.h>
#include <sync/recursive_mutex.h>
#include <stddef.h>
#include <assert.h>
#include <limits.h>

#include <sel4/sel4.h>
#ifdef CONFIG_DEBUG_BUILD
#include <sel4debug/debug.h>
#endif

static void *thread_id(void)
{
    return (void *)seL4_GetIPCBuffer();
}

int sync_recursive_mutex_init(sync_recursive_mutex_t *mutex, seL4_CPtr notification)
{
    if (mutex == NULL) {
        ZF_LOGE("Mutex passed to sync_recursive_mutex_init is NULL");
        return -1;
    }
#ifdef CONFIG_DEBUG_BUILD
    /* Check the cap actually is a notification. */
    assert(debug_cap_is_notification(notification));
#endif

    mutex->notification.cptr = notification;
    mutex->owner = NULL;
    mutex->held = 0;

    /* Prime the endpoint. */
    seL4_Signal(mutex->notification.cptr);
    return 0;
}

int sync_recursive_mutex_lock(sync_recursive_mutex_t *mutex)
{
    if (mutex == NULL) {
        ZF_LOGE("Mutex passed to sync_recursive_mutex_lock is NULL");
        return -1;
    }
    if (thread_id() != mutex->owner) {
        /* We don't already have the mutex. */
        seL4_Wait(mutex->notification.cptr, NULL);
        __atomic_thread_fence(__ATOMIC_ACQUIRE);
        assert(mutex->owner == NULL);
        mutex->owner = thread_id();
        assert(mutex->held == 0);
    }
    if (mutex->held == UINT_MAX) {
        /* We would overflow if we re-acquired the mutex. Note that we can only
         * be in this branch if we already held the mutex before entering this
         * function, so we don't need to release the mutex here.
         */
        return -1;
    }
    mutex->held++;
    return 0;
}

int sync_recursive_mutex_unlock(sync_recursive_mutex_t *mutex)
{
    if (mutex == NULL) {
        ZF_LOGE("Mutex passed to sync_recursive_mutex_lock is NULL");
        return -1;
    }
    assert(mutex->owner == thread_id());
    assert(mutex->held > 0);
    mutex->held--;
    if (mutex->held == 0) {
        /* This was the outermost lock we held. Wake the next person up. */
        __atomic_store_n(&mutex->owner, NULL, __ATOMIC_RELEASE);
        seL4_Signal(mutex->notification.cptr);
    }
    return 0;
}

int sync_recursive_mutex_new(vka_t *vka, sync_recursive_mutex_t *mutex)
{
    int error = vka_alloc_notification(vka, &(mutex->notification));

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

int sync_recursive_mutex_destroy(vka_t *vka, sync_recursive_mutex_t *mutex)
{
    vka_free_object(vka, &(mutex->notification));
    return 0;
}
