/*
 * QEMU Thread Context
 *
 * Copyright Red Hat Inc., 2022
 *
 * Authors:
 *  David Hildenbrand <david@redhat.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qemu/thread-context.h"
#include "qapi/error.h"
#include "qapi/qapi-builtin-visit.h"
#include "qapi/visitor.h"
#include "qemu/config-file.h"
#include "qapi/qapi-builtin-visit.h"
#include "qom/object_interfaces.h"
#include "qemu/module.h"
#include "qemu/bitmap.h"

#ifdef CONFIG_NUMA
#include <numa.h>
#endif

enum {
    TC_CMD_NONE = 0,
    TC_CMD_STOP,
    TC_CMD_NEW,
};

typedef struct ThreadContextCmdNew {
    QemuThread *thread;
    const char *name;
    void *(*start_routine)(void *);
    void *arg;
    int mode;
} ThreadContextCmdNew;

static void *thread_context_run(void *opaque)
{
    ThreadContext *tc = opaque;

    tc->thread_id = qemu_get_thread_id();
    qemu_sem_post(&tc->sem);

    while (true) {
        /*
         * Threads inherit the CPU affinity of the creating thread. For this
         * reason, we create new (especially short-lived) threads from our
         * persistent context thread.
         *
         * Especially when QEMU is not allowed to set the affinity itself,
         * management tools can simply set the affinity of the context thread
         * after creating the context, to have new threads created via
         * the context inherit the CPU affinity automatically.
         */
        switch (tc->thread_cmd) {
        case TC_CMD_NONE:
            break;
        case TC_CMD_STOP:
            tc->thread_cmd = TC_CMD_NONE;
            qemu_sem_post(&tc->sem);
            return NULL;
        case TC_CMD_NEW: {
            ThreadContextCmdNew *cmd_new = tc->thread_cmd_data;

            qemu_thread_create(cmd_new->thread, cmd_new->name,
                               cmd_new->start_routine, cmd_new->arg,
                               cmd_new->mode);
            tc->thread_cmd = TC_CMD_NONE;
            tc->thread_cmd_data = NULL;
            qemu_sem_post(&tc->sem);
            break;
        }
        default:
            g_assert_not_reached();
        }
        qemu_sem_wait(&tc->sem_thread);
    }
}

static void thread_context_set_cpu_affinity(Object *obj, Visitor *v,
                                            const char *name, void *opaque,
                                            Error **errp)
{
    ThreadContext *tc = THREAD_CONTEXT(obj);
    uint16List *l, *host_cpus = NULL;
    unsigned long *bitmap = NULL;
    int nbits = 0, ret;

    if (tc->init_cpu_bitmap) {
        error_setg(errp, "Mixing CPU and node affinity not supported");
        return;
    }

    if (!visit_type_uint16List(v, name, &host_cpus, errp)) {
        return;
    }

    if (!host_cpus) {
        error_setg(errp, "CPU list is empty");
        goto out;
    }

    for (l = host_cpus; l; l = l->next) {
        nbits = MAX(nbits, l->value + 1);
    }
    bitmap = bitmap_new(nbits);
    for (l = host_cpus; l; l = l->next) {
        set_bit(l->value, bitmap);
    }

    if (tc->thread_id != -1) {
        /*
         * Note: we won't be adjusting the affinity of any thread that is still
         * around, but only the affinity of the context thread.
         */
        ret = qemu_thread_set_affinity(&tc->thread, bitmap, nbits);
        if (ret) {
            error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret));
        }
    } else {
        tc->init_cpu_bitmap = bitmap;
        bitmap = NULL;
        tc->init_cpu_nbits = nbits;
    }
out:
    g_free(bitmap);
    qapi_free_uint16List(host_cpus);
}

static void thread_context_get_cpu_affinity(Object *obj, Visitor *v,
                                            const char *name, void *opaque,
                                            Error **errp)
{
    unsigned long *bitmap, nbits, value;
    ThreadContext *tc = THREAD_CONTEXT(obj);
    uint16List *host_cpus = NULL;
    uint16List **tail = &host_cpus;
    int ret;

    if (tc->thread_id == -1) {
        error_setg(errp, "Object not initialized yet");
        return;
    }

    ret = qemu_thread_get_affinity(&tc->thread, &bitmap, &nbits);
    if (ret) {
        error_setg(errp, "Getting CPU affinity failed: %s", strerror(ret));
        return;
    }

    value = find_first_bit(bitmap, nbits);
    while (value < nbits) {
        QAPI_LIST_APPEND(tail, value);

        value = find_next_bit(bitmap, nbits, value + 1);
    }
    g_free(bitmap);

    visit_type_uint16List(v, name, &host_cpus, errp);
    qapi_free_uint16List(host_cpus);
}

static void thread_context_set_node_affinity(Object *obj, Visitor *v,
                                             const char *name, void *opaque,
                                             Error **errp)
{
#ifdef CONFIG_NUMA
    const int nbits = numa_num_possible_cpus();
    ThreadContext *tc = THREAD_CONTEXT(obj);
    uint16List *l, *host_nodes = NULL;
    unsigned long *bitmap = NULL;
    struct bitmask *tmp_cpus;
    int ret, i;

    if (tc->init_cpu_bitmap) {
        error_setg(errp, "Mixing CPU and node affinity not supported");
        return;
    }

    if (!visit_type_uint16List(v, name, &host_nodes, errp)) {
        return;
    }

    if (!host_nodes) {
        error_setg(errp, "Node list is empty");
        goto out;
    }

    bitmap = bitmap_new(nbits);
    tmp_cpus = numa_allocate_cpumask();
    for (l = host_nodes; l; l = l->next) {
        numa_bitmask_clearall(tmp_cpus);
        ret = numa_node_to_cpus(l->value, tmp_cpus);
        if (ret) {
            /* We ignore any errors, such as impossible nodes. */
            continue;
        }
        for (i = 0; i < nbits; i++) {
            if (numa_bitmask_isbitset(tmp_cpus, i)) {
                set_bit(i, bitmap);
            }
        }
    }
    numa_free_cpumask(tmp_cpus);

    if (bitmap_empty(bitmap, nbits)) {
        error_setg(errp, "The nodes select no CPUs");
        goto out;
    }

    if (tc->thread_id != -1) {
        /*
         * Note: we won't be adjusting the affinity of any thread that is still
         * around for now, but only the affinity of the context thread.
         */
        ret = qemu_thread_set_affinity(&tc->thread, bitmap, nbits);
        if (ret) {
            error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret));
        }
    } else {
        tc->init_cpu_bitmap = bitmap;
        bitmap = NULL;
        tc->init_cpu_nbits = nbits;
    }
out:
    g_free(bitmap);
    qapi_free_uint16List(host_nodes);
#else
    error_setg(errp, "NUMA node affinity is not supported by this QEMU");
#endif
}

static void thread_context_get_thread_id(Object *obj, Visitor *v,
                                         const char *name, void *opaque,
                                         Error **errp)
{
    ThreadContext *tc = THREAD_CONTEXT(obj);
    uint64_t value = tc->thread_id;

    visit_type_uint64(v, name, &value, errp);
}

static void thread_context_instance_complete(UserCreatable *uc, Error **errp)
{
    ThreadContext *tc = THREAD_CONTEXT(uc);
    char *thread_name;
    int ret;

    thread_name = g_strdup_printf("TC %s",
                               object_get_canonical_path_component(OBJECT(uc)));
    qemu_thread_create(&tc->thread, thread_name, thread_context_run, tc,
                       QEMU_THREAD_JOINABLE);
    g_free(thread_name);

    /* Wait until initialization of the thread is done. */
    while (tc->thread_id == -1) {
        qemu_sem_wait(&tc->sem);
    }

    if (tc->init_cpu_bitmap) {
        ret = qemu_thread_set_affinity(&tc->thread, tc->init_cpu_bitmap,
                                       tc->init_cpu_nbits);
        if (ret) {
            error_setg(errp, "Setting CPU affinity failed: %s", strerror(ret));
        }
        g_free(tc->init_cpu_bitmap);
        tc->init_cpu_bitmap = NULL;
    }
}

static void thread_context_class_init(ObjectClass *oc, void *data)
{
    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);

    ucc->complete = thread_context_instance_complete;
    object_class_property_add(oc, "thread-id", "int",
                              thread_context_get_thread_id, NULL, NULL,
                              NULL);
    object_class_property_add(oc, "cpu-affinity", "int",
                              thread_context_get_cpu_affinity,
                              thread_context_set_cpu_affinity, NULL, NULL);
    object_class_property_add(oc, "node-affinity", "int", NULL,
                              thread_context_set_node_affinity, NULL, NULL);
}

static void thread_context_instance_init(Object *obj)
{
    ThreadContext *tc = THREAD_CONTEXT(obj);

    tc->thread_id = -1;
    qemu_sem_init(&tc->sem, 0);
    qemu_sem_init(&tc->sem_thread, 0);
    qemu_mutex_init(&tc->mutex);
}

static void thread_context_instance_finalize(Object *obj)
{
    ThreadContext *tc = THREAD_CONTEXT(obj);

    if (tc->thread_id != -1) {
        tc->thread_cmd = TC_CMD_STOP;
        qemu_sem_post(&tc->sem_thread);
        qemu_thread_join(&tc->thread);
    }
    qemu_sem_destroy(&tc->sem);
    qemu_sem_destroy(&tc->sem_thread);
    qemu_mutex_destroy(&tc->mutex);
}

static const TypeInfo thread_context_info = {
    .name = TYPE_THREAD_CONTEXT,
    .parent = TYPE_OBJECT,
    .class_init = thread_context_class_init,
    .instance_size = sizeof(ThreadContext),
    .instance_init = thread_context_instance_init,
    .instance_finalize = thread_context_instance_finalize,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_USER_CREATABLE },
        { }
    }
};

static void thread_context_register_types(void)
{
    type_register_static(&thread_context_info);
}
type_init(thread_context_register_types)

void thread_context_create_thread(ThreadContext *tc, QemuThread *thread,
                                  const char *name,
                                  void *(*start_routine)(void *), void *arg,
                                  int mode)
{
    ThreadContextCmdNew data = {
        .thread = thread,
        .name = name,
        .start_routine = start_routine,
        .arg = arg,
        .mode = mode,
    };

    qemu_mutex_lock(&tc->mutex);
    tc->thread_cmd = TC_CMD_NEW;
    tc->thread_cmd_data = &data;
    qemu_sem_post(&tc->sem_thread);

    while (tc->thread_cmd != TC_CMD_NONE) {
        qemu_sem_wait(&tc->sem);
    }
    qemu_mutex_unlock(&tc->mutex);
}
