// Copyright 2017 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 "tests.h"

#include <err.h>
#include <inttypes.h>
#include <malloc.h>
#include <platform.h>
#include <stdio.h>

#include <kernel/event.h>
#include <kernel/thread.h>
#include <kernel/timer.h>

#include <fbl/algorithm.h>
#include <fbl/atomic.h>
#include <zircon/types.h>

static void timer_cb(timer_t* timer, zx_time_t now, void* arg) {
    event_t* event = (event_t*)arg;
    event_signal(event, true);
}

static int timer_do_one_thread(void* arg) {
    event_t event;
    timer_t timer;

    event_init(&event, false, 0);
    timer_init(&timer);

    timer_set(&timer, current_time() + ZX_MSEC(10), TIMER_SLACK_CENTER, 0, timer_cb, &event);
    event_wait(&event);

    printf("got timer on cpu %u\n", arch_curr_cpu_num());

    event_destroy(&event);

    return 0;
}

static void timer_test_all_cpus(void) {
    thread_t* timer_threads[SMP_MAX_CPUS];
    uint max = arch_max_num_cpus();

    uint i;
    for (i = 0; i < max; i++) {
        char name[16];
        snprintf(name, sizeof(name), "timer %u\n", i);

        timer_threads[i] = thread_create_etc(
            NULL, name, timer_do_one_thread, NULL,
            DEFAULT_PRIORITY, NULL, NULL, DEFAULT_STACK_SIZE, NULL);
        if (timer_threads[i] == NULL) {
            printf("failed to create thread for cpu %u\n", i);
            return;
        }
        thread_set_cpu_affinity(timer_threads[i], cpu_num_to_mask(i));
        thread_resume(timer_threads[i]);
    }
    uint joined = 0;
    for (i = 0; i < max; i++) {
        if (thread_join(timer_threads[i], NULL, ZX_SEC(1)) == 0) {
            joined += 1;
        }
    }
    printf("%u threads created, %u threads joined\n", max, joined);
}

static void timer_cb2(timer_t* timer, zx_time_t now, void* arg) {
    auto timer_count = static_cast<fbl::atomic<size_t>*>(arg);
    timer_count->fetch_add(1);
    thread_preempt_set_pending();
}

static void timer_test_coalescing(enum slack_mode mode, uint64_t slack,
                                  const zx_time_t* deadline, const int64_t* expected_adj, size_t count) {
    printf("testing coalsecing mode %d\n", mode);

    fbl::atomic<size_t> timer_count(0);

    timer_t* timer = (timer_t*)malloc(sizeof(timer_t) * count);

    printf("       orig         new       adjustment\n");
    for (size_t ix = 0; ix != count; ++ix) {
        timer_init(&timer[ix]);
        zx_time_t dl = deadline[ix];
        timer_set(&timer[ix], dl, mode, slack, timer_cb2, &timer_count);
        printf("[%zu] %" PRIu64 "  -> %" PRIu64 ", %" PRIi64 "\n",
               ix, dl, timer[ix].scheduled_time, timer[ix].slack);

        if (timer[ix].slack != expected_adj[ix]) {
            printf("\n!! unexpected adjustment! expected %" PRIi64 "\n", expected_adj[ix]);
        }
    }

    // Wait for the timers to fire.
    while (timer_count.load() != count) {
        thread_sleep(current_time() + ZX_MSEC(5));
    }

    free(timer);
}

static void timer_test_coalescing_center(void) {
    zx_time_t when = current_time() + ZX_MSEC(1);
    zx_duration_t off = ZX_USEC(10);
    zx_duration_t slack = 2u * off;

    const zx_time_t deadline[] = {
        when + (6u * off), // non-coalesced, adjustment = 0
        when,              // non-coalesced, adjustment = 0
        when - off,        // coalesced with [1], adjustment = 10u
        when - (3u * off), // non-coalesced, adjustment = 0
        when + off,        // coalesced with [1], adjustment = -10u
        when + (3u * off), // non-coalesced, adjustment = 0
        when + (5u * off), // coalesced with [0], adjustment = 10u
        when - (3u * off), // non-coalesced, same as [3], adjustment = 0
    };

    const int64_t expected_adj[fbl::count_of(deadline)] = {
        0, 0, ZX_USEC(10), 0, -(int64_t)ZX_USEC(10), 0, ZX_USEC(10), 0};

    timer_test_coalescing(
        TIMER_SLACK_CENTER, slack, deadline, expected_adj, fbl::count_of(deadline));
}

static void timer_test_coalescing_late(void) {
    zx_time_t when = current_time() + ZX_MSEC(1);
    zx_duration_t off = ZX_USEC(10);
    zx_duration_t slack = 3u * off;

    const zx_time_t deadline[] = {
        when + off,        // non-coalesced, adjustment = 0
        when + (2u * off), // non-coalesced, adjustment = 0
        when - off,        // coalesced with [0], adjustment = 20u
        when - (3u * off), // non-coalesced, adjustment = 0
        when + (3u * off), // non-coalesced, adjustment = 0
        when + (2u * off), // non-coalesced, same as [1]
        when - (4u * off), // coalesced with [3], adjustment = 10u
    };

    const int64_t expected_adj[fbl::count_of(deadline)] = {
        0, 0, ZX_USEC(20), 0, 0, 0, ZX_USEC(10)};

    timer_test_coalescing(
        TIMER_SLACK_LATE, slack, deadline, expected_adj, fbl::count_of(deadline));
}

static void timer_test_coalescing_early(void) {
    zx_time_t when = current_time() + ZX_MSEC(1);
    zx_duration_t off = ZX_USEC(10);
    zx_duration_t slack = 3u * off;

    const zx_time_t deadline[] = {
        when,              // non-coalesced, adjustment = 0
        when + (2u * off), // coalesced with [0], adjustment = -20u
        when - off,        // non-coalesced, adjustment = 0
        when - (3u * off), // non-coalesced, adjustment = 0
        when + (4u * off), // non-coalesced, adjustment = 0
        when + (5u * off), // coalesced with [4], adjustment = -10u
        when - (2u * off), // coalesced with [3], adjustment = -10u
    };

    const int64_t expected_adj[fbl::count_of(deadline)] = {
        0, -(int64_t)ZX_USEC(20), 0, 0, 0, -(int64_t)ZX_USEC(10), -(int64_t)ZX_USEC(10)};

    timer_test_coalescing(
        TIMER_SLACK_EARLY, slack, deadline, expected_adj, fbl::count_of(deadline));
}

static void timer_far_deadline(void) {
    event_t event;
    timer_t timer;

    event_init(&event, false, 0);
    timer_init(&timer);

    timer_set(&timer, UINT64_MAX - 5, TIMER_SLACK_CENTER, 0, timer_cb, &event);
    zx_status_t st = event_wait_deadline(&event, current_time() + ZX_MSEC(100), false);
    if (st != ZX_ERR_TIMED_OUT) {
        printf("error: unexpected timer fired!\n");
    } else {
        timer_cancel(&timer);
    }

    event_destroy(&event);
}

int timer_tests(int, const cmd_args*, uint32_t) {
    timer_test_coalescing_center();
    timer_test_coalescing_late();
    timer_test_coalescing_early();
    timer_test_all_cpus();
    timer_far_deadline();
    return 0;
}
