/*
 * GThread coroutine initialization code
 *
 * Copyright (C) 2006  Anthony Liguori <anthony@codemonkey.ws>
 * Copyright (C) 2011  Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.0 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/coroutine_int.h"

typedef struct {
    Coroutine base;
    GThread *thread;
    bool runnable;
    bool free_on_thread_exit;
    CoroutineAction action;
} CoroutineGThread;

static CompatGMutex coroutine_lock;
static CompatGCond coroutine_cond;

/* GLib 2.31 and beyond deprecated various parts of the thread API,
 * but the new interfaces are not available in older GLib versions
 * so we have to cope with both.
 */
#if GLIB_CHECK_VERSION(2, 31, 0)
/* Awkwardly, the GPrivate API doesn't provide a way to update the
 * GDestroyNotify handler for the coroutine key dynamically. So instead
 * we track whether or not the CoroutineGThread should be freed on
 * thread exit / coroutine key update using the free_on_thread_exit
 * field.
 */
static void coroutine_destroy_notify(gpointer data)
{
    CoroutineGThread *co = data;
    if (co && co->free_on_thread_exit) {
        g_free(co);
    }
}

static GPrivate coroutine_key = G_PRIVATE_INIT(coroutine_destroy_notify);

static inline CoroutineGThread *get_coroutine_key(void)
{
    return g_private_get(&coroutine_key);
}

static inline void set_coroutine_key(CoroutineGThread *co,
                                     bool free_on_thread_exit)
{
    /* Unlike g_static_private_set() this does not call the GDestroyNotify
     * if the previous value of the key was NULL. Fortunately we only need
     * the GDestroyNotify in the non-NULL key case.
     */
    co->free_on_thread_exit = free_on_thread_exit;
    g_private_replace(&coroutine_key, co);
}

static inline GThread *create_thread(GThreadFunc func, gpointer data)
{
    return g_thread_new("coroutine", func, data);
}

#else

/* Handle older GLib versions */

static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT;

static inline CoroutineGThread *get_coroutine_key(void)
{
    return g_static_private_get(&coroutine_key);
}

static inline void set_coroutine_key(CoroutineGThread *co,
                                     bool free_on_thread_exit)
{
    g_static_private_set(&coroutine_key, co,
                         free_on_thread_exit ? (GDestroyNotify)g_free : NULL);
}

static inline GThread *create_thread(GThreadFunc func, gpointer data)
{
    return g_thread_create_full(func, data, 0, TRUE, TRUE,
                                G_THREAD_PRIORITY_NORMAL, NULL);
}

#endif


static void __attribute__((constructor)) coroutine_init(void)
{
#if !GLIB_CHECK_VERSION(2, 31, 0)
    if (!g_thread_supported()) {
        g_thread_init(NULL);
    }
#endif
}

static void coroutine_wait_runnable_locked(CoroutineGThread *co)
{
    while (!co->runnable) {
        g_cond_wait(&coroutine_cond, &coroutine_lock);
    }
}

static void coroutine_wait_runnable(CoroutineGThread *co)
{
    g_mutex_lock(&coroutine_lock);
    coroutine_wait_runnable_locked(co);
    g_mutex_unlock(&coroutine_lock);
}

static gpointer coroutine_thread(gpointer opaque)
{
    CoroutineGThread *co = opaque;

    set_coroutine_key(co, false);
    coroutine_wait_runnable(co);
    co->base.entry(co->base.entry_arg);
    qemu_coroutine_switch(&co->base, co->base.caller, COROUTINE_TERMINATE);
    return NULL;
}

Coroutine *qemu_coroutine_new(void)
{
    CoroutineGThread *co;

    co = g_malloc0(sizeof(*co));
    co->thread = create_thread(coroutine_thread, co);
    if (!co->thread) {
        g_free(co);
        return NULL;
    }
    return &co->base;
}

void qemu_coroutine_delete(Coroutine *co_)
{
    CoroutineGThread *co = DO_UPCAST(CoroutineGThread, base, co_);

    g_thread_join(co->thread);
    g_free(co);
}

CoroutineAction qemu_coroutine_switch(Coroutine *from_,
                                      Coroutine *to_,
                                      CoroutineAction action)
{
    CoroutineGThread *from = DO_UPCAST(CoroutineGThread, base, from_);
    CoroutineGThread *to = DO_UPCAST(CoroutineGThread, base, to_);

    g_mutex_lock(&coroutine_lock);
    from->runnable = false;
    from->action = action;
    to->runnable = true;
    to->action = action;
    g_cond_broadcast(&coroutine_cond);

    if (action != COROUTINE_TERMINATE) {
        coroutine_wait_runnable_locked(from);
    }
    g_mutex_unlock(&coroutine_lock);
    return from->action;
}

Coroutine *qemu_coroutine_self(void)
{
    CoroutineGThread *co = get_coroutine_key();
    if (!co) {
        co = g_malloc0(sizeof(*co));
        co->runnable = true;
        set_coroutine_key(co, true);
    }

    return &co->base;
}

bool qemu_in_coroutine(void)
{
    CoroutineGThread *co = get_coroutine_key();

    return co && co->base.caller;
}
