// 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 <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) {
    int* timer_count = (int*)arg;
    atomic_add(timer_count, 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, int count) {
    printf("testing coalsecing mode %d\n", mode);

    int timer_count = 0;

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

    printf("       orig         new       adjustment\n");
    for (int 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("[%d] %" 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 (atomic_load(&timer_count) != 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[countof(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, countof(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[countof(deadline)] = {
        0, 0, ZX_USEC(20), 0, 0, 0, ZX_USEC(10)};

    timer_test_coalescing(
        TIMER_SLACK_LATE, slack, deadline, expected_adj, countof(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[countof(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, countof(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);
}

void timer_tests(void) {
    timer_test_coalescing_center();
    timer_test_coalescing_late();
    timer_test_coalescing_early();
    timer_test_all_cpus();
    timer_far_deadline();
}
