// 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 <err.h>
#include <inttypes.h>
#include <lib/unittest/unittest.h>
#include <malloc.h>
#include <platform.h>
#include <pow2.h>
#include <rand.h>
#include <stdio.h>
#include <zircon/time.h>
#include <zircon/types.h>

#include <fbl/algorithm.h>
#include <kernel/auto_lock.h>
#include <kernel/event.h>
#include <kernel/mp.h>
#include <kernel/spinlock.h>
#include <kernel/thread.h>
#include <kernel/timer.h>
#include <ktl/atomic.h>

#include "tests.h"

static void timer_diag_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);

  const Deadline deadline = Deadline::no_slack(current_time() + ZX_MSEC(10));
  timer_set(&timer, deadline, timer_diag_cb, &event);
  event_wait(&event);

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

  event_destroy(&event);

  return 0;
}

static void timer_diag_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);
    DEBUG_ASSERT_MSG(timer_threads[i] != NULL, "failed to create thread for cpu %u\n", i);
    thread_set_cpu_affinity(timer_threads[i], cpu_num_to_mask(i));
    thread_resume(timer_threads[i]);
  }
  for (i = 0; i < max; i++) {
    zx_status_t status = thread_join(timer_threads[i], NULL, ZX_TIME_INFINITE);
    DEBUG_ASSERT_MSG(status == ZX_OK, "failed to join thread for cpu %u: %d\n", i, status);
  }
}

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

static void timer_diag_coalescing(TimerSlack slack, const zx_time_t* deadline,
                                  const zx_duration_t* expected_adj, size_t count) {
  printf("testing coalsecing mode %u\n", slack.mode());

  ktl::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]);
    const Deadline dl(deadline[ix], slack);
    timer_set(&timer[ix], dl, timer_diag_cb2, &timer_count);
    printf("[%zu] %" PRIi64 "  -> %" PRIi64 ", %" PRIi64 "\n", ix, dl.when(),
           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_diag_coalescing_center(void) {
  zx_time_t when = current_time() + ZX_MSEC(1);
  zx_duration_t off = ZX_USEC(10);
  TimerSlack slack = {2u * off, TIMER_SLACK_CENTER};

  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 zx_duration_t expected_adj[fbl::count_of(deadline)] = {
      0, 0, ZX_USEC(10), 0, -ZX_USEC(10), 0, ZX_USEC(10), 0};

  timer_diag_coalescing(slack, deadline, expected_adj, fbl::count_of(deadline));
}

static void timer_diag_coalescing_late(void) {
  zx_time_t when = current_time() + ZX_MSEC(1);
  zx_duration_t off = ZX_USEC(10);
  TimerSlack slack = {3u * off, TIMER_SLACK_LATE};

  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 zx_duration_t expected_adj[fbl::count_of(deadline)] = {0, 0, ZX_USEC(20), 0,
                                                               0, 0, ZX_USEC(10)};

  timer_diag_coalescing(slack, deadline, expected_adj, fbl::count_of(deadline));
}

static void timer_diag_coalescing_early(void) {
  zx_time_t when = current_time() + ZX_MSEC(1);
  zx_duration_t off = ZX_USEC(10);
  TimerSlack slack = {3u * off, TIMER_SLACK_EARLY};

  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 zx_duration_t expected_adj[fbl::count_of(deadline)] = {0, -ZX_USEC(20), 0,           0,
                                                               0, -ZX_USEC(10), -ZX_USEC(10)};

  timer_diag_coalescing(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);

  const Deadline deadline = Deadline::no_slack(ZX_TIME_INFINITE - 5);
  timer_set(&timer, deadline, timer_diag_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);
}

// Print timer diagnostics for manual review.
int timer_diag(int, const cmd_args*, uint32_t) {
  timer_diag_coalescing_center();
  timer_diag_coalescing_late();
  timer_diag_coalescing_early();
  timer_diag_all_cpus();
  timer_far_deadline();
  return 0;
}

struct timer_stress_args {
  volatile int timer_stress_done;
  volatile uint64_t num_set;
  volatile uint64_t num_fired;
};

static void timer_stress_cb(struct timer* t, zx_time_t now, void* void_arg) {
  timer_stress_args* args = reinterpret_cast<timer_stress_args*>(void_arg);
  atomic_add_u64(&args->num_fired, 1);
}

// Returns a random duration between 0 and max (inclusive).
static zx_duration_t rand_duration(zx_duration_t max) {
  return (zx_duration_mul_int64(max, rand())) / RAND_MAX;
}

static int timer_stress_worker(void* void_arg) {
  timer_stress_args* args = reinterpret_cast<timer_stress_args*>(void_arg);
  while (!atomic_load(&args->timer_stress_done)) {
    timer_t t = TIMER_INITIAL_VALUE(t);
    zx_duration_t timer_duration = rand_duration(ZX_MSEC(5));

    // Set a timer, then switch to a different CPU to ensure we race with it.

    arch_disable_ints();
    uint timer_cpu = arch_curr_cpu_num();
    const Deadline deadline = Deadline::no_slack(current_time() + timer_duration);
    timer_set(&t, deadline, timer_stress_cb, void_arg);
    thread_set_cpu_affinity(get_current_thread(), ~cpu_num_to_mask(timer_cpu));
    DEBUG_ASSERT(arch_curr_cpu_num() != timer_cpu);
    arch_enable_ints();

    // We're now running on something other than timer_cpu.

    atomic_add_u64(&args->num_set, 1);

    // Sleep for the timer duration so that this thread's timer_cancel races with the timer
    // callback. We want to race to ensure there are no synchronization or memory visibility
    // issues.
    thread_sleep_relative(timer_duration);
    timer_cancel(&t);
  }
  return 0;
}

static unsigned get_num_cpus_online() {
  unsigned count = 0;
  cpu_mask_t online = mp_get_online_mask();
  while (online) {
    online >>= 1;
    ++count;
  }
  return count;
}

// timer_stress is a simple stress test intended to flush out bugs in kernel timers.
int timer_stress(int argc, const cmd_args* argv, uint32_t) {
  if (argc < 2) {
    printf("not enough args\n");
    printf("usage: %s <num seconds>\n", argv[0].str);
    return ZX_ERR_INTERNAL;
  }

  // We need 2 or more CPUs for this test.
  if (get_num_cpus_online() < 2) {
    printf("not enough online cpus\n");
    return ZX_ERR_INTERNAL;
  }

  timer_stress_args args{};

  thread_t* threads[256];
  for (auto& thread : threads) {
    thread = thread_create("timer-stress-worker", &timer_stress_worker, &args, DEFAULT_PRIORITY);
  }

  printf("running for %zu seconds\n", argv[1].u);
  for (const auto& thread : threads) {
    thread_resume(thread);
  }

  thread_sleep_relative(ZX_SEC(argv[1].u));
  atomic_store(&args.timer_stress_done, 1);

  for (const auto& thread : threads) {
    thread_join(thread, nullptr, ZX_TIME_INFINITE);
  }

  printf("timer stress done; timer set %zu, timer fired %zu\n", args.num_set, args.num_fired);
  return 0;
}

struct timer_args {
  volatile int result;
  volatile int timer_fired;
  volatile int remaining;
  volatile int wait;
  spin_lock_t* lock;
};

static void timer_cb(struct timer*, zx_time_t now, void* void_arg) {
  timer_args* arg = reinterpret_cast<timer_args*>(void_arg);
  atomic_store(&arg->timer_fired, 1);
}

// Set a timer and cancel it before the deadline has elapsed.
static bool cancel_before_deadline() {
  BEGIN_TEST;
  timer_args arg{};
  timer_t t = TIMER_INITIAL_VALUE(t);
  const Deadline deadline = Deadline::no_slack(current_time() + ZX_HOUR(5));
  timer_set(&t, deadline, timer_cb, &arg);
  ASSERT_TRUE(timer_cancel(&t), "");
  ASSERT_FALSE(atomic_load(&arg.timer_fired), "");
  END_TEST;
}

// Set a timer and cancel it after it has fired.
static bool cancel_after_fired() {
  BEGIN_TEST;
  timer_args arg{};
  timer_t t = TIMER_INITIAL_VALUE(t);
  const Deadline deadline = Deadline::no_slack(current_time());
  timer_set(&t, deadline, timer_cb, &arg);
  while (!atomic_load(&arg.timer_fired)) {
  }
  ASSERT_FALSE(timer_cancel(&t), "");
  END_TEST;
}

static void timer_cancel_cb(struct timer* t, zx_time_t now, void* void_arg) {
  timer_args* arg = reinterpret_cast<timer_args*>(void_arg);
  atomic_store(&arg->result, timer_cancel(t));
  atomic_store(&arg->timer_fired, 1);
}

// Set a timer and cancel it from its own callback.
static bool cancel_from_callback() {
  BEGIN_TEST;
  timer_args arg{};
  arg.result = 1;
  timer_t t = TIMER_INITIAL_VALUE(t);
  const Deadline deadline = Deadline::no_slack(current_time());
  timer_set(&t, deadline, timer_cancel_cb, &arg);
  while (!atomic_load(&arg.timer_fired)) {
  }
  ASSERT_FALSE(arg.result, "");
  ASSERT_FALSE(timer_cancel(&t), "");
  END_TEST;
}

static void timer_set_cb(struct timer* t, zx_time_t now, void* void_arg) {
  timer_args* arg = reinterpret_cast<timer_args*>(void_arg);
  if (atomic_add(&arg->remaining, -1) >= 1) {
    const Deadline deadline = Deadline::no_slack(current_time() + ZX_USEC(10));
    timer_set(t, deadline, timer_set_cb, void_arg);
  }
}

// Set a timer that re-sets itself from its own callback.
static bool set_from_callback() {
  BEGIN_TEST;
  timer_args arg{};
  arg.remaining = 5;
  timer_t t = TIMER_INITIAL_VALUE(t);
  const Deadline deadline = Deadline::no_slack(current_time());
  timer_set(&t, deadline, timer_set_cb, &arg);
  while (atomic_load(&arg.remaining) > 0) {
  }

  // We cannot assert the return value below because we don't know if the last timer has fired.
  timer_cancel(&t);

  END_TEST;
}

static void timer_trylock_cb(struct timer* t, zx_time_t now, void* void_arg) {
  timer_args* arg = reinterpret_cast<timer_args*>(void_arg);
  atomic_store(&arg->timer_fired, 1);
  while (atomic_load(&arg->wait)) {
  }

  int result = timer_trylock_or_cancel(t, arg->lock);
  if (!result) {
    spin_unlock(arg->lock);
  }

  atomic_store(&arg->result, result);
}

// See that timer_trylock_or_cancel spins until the timer is canceled.
static bool trylock_or_cancel_canceled() {
  BEGIN_TEST;

  // We need 2 or more CPUs for this test.
  if (get_num_cpus_online() < 2) {
    printf("skipping test trylock_or_cancel_canceled, not enough online cpus\n");
    return true;
  }

  timer_args arg{};
  timer_t t = TIMER_INITIAL_VALUE(t);

  SpinLock lock;
  arg.lock = lock.GetInternal();
  arg.wait = 1;

  arch_disable_ints();

  uint timer_cpu = arch_curr_cpu_num();
  const Deadline deadline = Deadline::no_slack(current_time() + ZX_USEC(100));
  timer_set(&t, deadline, timer_trylock_cb, &arg);

  // The timer is set to run on timer_cpu, switch to a different CPU, acquire the spinlock then
  // signal the callback to proceed.
  thread_set_cpu_affinity(get_current_thread(), ~cpu_num_to_mask(timer_cpu));
  DEBUG_ASSERT(arch_curr_cpu_num() != timer_cpu);

  arch_enable_ints();

  {
    AutoSpinLock guard(&lock);

    while (!atomic_load(&arg.timer_fired)) {
    }

    // Callback should now be running. Tell it to stop waiting and start trylocking.
    atomic_store(&arg.wait, 0);

    // See that timer_cancel returns false indicating that the timer ran.
    ASSERT_FALSE(timer_cancel(&t), "");
  }

  // See that the timer failed to acquire the lock.
  ASSERT_TRUE(arg.result, "");
  END_TEST;
}

// See that timer_trylock_or_cancel acquires the lock when the holder releases it.
static bool trylock_or_cancel_get_lock() {
  BEGIN_TEST;

  // We need 2 or more CPUs for this test.
  if (get_num_cpus_online() < 2) {
    printf("skipping test trylock_or_cancel_get_lock, not enough online cpus\n");
    return true;
  }

  timer_args arg{};
  timer_t t = TIMER_INITIAL_VALUE(t);

  SpinLock lock;
  arg.lock = lock.GetInternal();
  arg.wait = 1;

  arch_disable_ints();

  uint timer_cpu = arch_curr_cpu_num();
  const Deadline deadline = Deadline::no_slack(current_time() + ZX_USEC(100));
  timer_set(&t, deadline, timer_trylock_cb, &arg);

  // The timer is set to run on timer_cpu, switch to a different CPU, acquire the spinlock then
  // signal the callback to proceed.
  thread_set_cpu_affinity(get_current_thread(), ~cpu_num_to_mask(timer_cpu));
  DEBUG_ASSERT(arch_curr_cpu_num() != timer_cpu);

  arch_enable_ints();

  {
    AutoSpinLock guard(&lock);

    while (!atomic_load(&arg.timer_fired)) {
    }

    // Callback should now be running. Tell it to stop waiting and start trylocking.
    atomic_store(&arg.wait, 0);
  }

  // See that timer_cancel returns false indicating that the timer ran.
  ASSERT_FALSE(timer_cancel(&t), "");

  // Note, we cannot assert the value of arg.result. We have both released the lock and canceled
  // the timer, but we don't know which of these events the timer observed first.

  END_TEST;
}

UNITTEST_START_TESTCASE(timer_tests)
UNITTEST("cancel_before_deadline", cancel_before_deadline)
UNITTEST("cancel_after_fired", cancel_after_fired)
UNITTEST("cancel_from_callback", cancel_from_callback)
UNITTEST("set_from_callback", set_from_callback)
UNITTEST("trylock_or_cancel_canceled", trylock_or_cancel_canceled)
UNITTEST("trylock_or_cancel_get_lock", trylock_or_cancel_get_lock)
UNITTEST_END_TESTCASE(timer_tests, "timer", "timer tests");
