// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <lib/dpc.h>

#include <assert.h>
#include <err.h>
#include <list.h>
#include <trace.h>

#include <kernel/event.h>
#include <kernel/spinlock.h>
#include <lk/init.h>

static spin_lock_t dpc_lock = SPIN_LOCK_INITIAL_VALUE;
static struct list_node dpc_list = LIST_INITIAL_VALUE(dpc_list);
static event_t dpc_event = EVENT_INITIAL_VALUE(dpc_event, false, 0);

zx_status_t dpc_queue(dpc_t *dpc, bool reschedule)
{
    DEBUG_ASSERT(dpc);
    DEBUG_ASSERT(dpc->func);

    if (list_in_list(&dpc->node))
        return ZX_OK;

    spin_lock_saved_state_t state;
    spin_lock_irqsave(&dpc_lock, state);

    // put the dpc at the tail of the list and signal the worker
    list_add_tail(&dpc_list, &dpc->node);
    event_signal(&dpc_event, false);

    spin_unlock_irqrestore(&dpc_lock, state);

    // reschedule here if asked to
    if (reschedule)
        thread_reschedule();

    return ZX_OK;
}

zx_status_t dpc_queue_thread_locked(dpc_t *dpc)
{
    DEBUG_ASSERT(dpc);
    DEBUG_ASSERT(dpc->func);

    if (list_in_list(&dpc->node))
        return ZX_OK;

    spin_lock_saved_state_t state;
    spin_lock_irqsave(&dpc_lock, state);

    // put the dpc at the tail of the list and signal the worker
    list_add_tail(&dpc_list, &dpc->node);
    event_signal_thread_locked(&dpc_event);

    spin_unlock_irqrestore(&dpc_lock, state);

    return ZX_OK;
}

bool dpc_cancel(dpc_t *dpc)
{
    DEBUG_ASSERT(dpc);

    spin_lock_saved_state_t state;
    spin_lock_irqsave(&dpc_lock, state);

    bool callback_not_running = false;

    if (list_in_list(&dpc->node)) {
        list_delete(&dpc->node);
        callback_not_running = true;
    }

    spin_unlock_irqrestore(&dpc_lock, state);
    return callback_not_running;
}

static int dpc_thread(void *arg)
{
    for (;;) {
        // wait for a dpc to fire
        __UNUSED zx_status_t err = event_wait(&dpc_event);
        DEBUG_ASSERT(err == ZX_OK);

        spin_lock_saved_state_t state;
        spin_lock_irqsave(&dpc_lock, state);

        // pop a dpc off the list
        dpc_t *dpc = list_remove_head_type(&dpc_list, dpc_t, node);

        // if the list is now empty, unsignal the event so we block until it is
        if (!dpc)
            event_unsignal(&dpc_event);

        spin_unlock_irqrestore(&dpc_lock, state);

        // call the dpc
        if (dpc && dpc->func)
            dpc->func(dpc);
    }


    return 0;
}

static void dpc_init(unsigned int level)
{
    thread_t *t = thread_create("dpc", &dpc_thread, NULL, DPC_THREAD_PRIORITY, DEFAULT_STACK_SIZE);
    thread_detach_and_resume(t);
}

LK_INIT_HOOK(dpc, dpc_init, LK_INIT_LEVEL_THREADING);
