// 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 "object/timer_dispatcher.h"

#include <assert.h>
#include <lib/counters.h>
#include <platform.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/rights.h>
#include <zircon/types.h>

#include <fbl/alloc_checker.h>
#include <fbl/auto_lock.h>
#include <kernel/thread.h>

KCOUNTER(dispatcher_timer_create_count, "dispatcher.timer.create")
KCOUNTER(dispatcher_timer_destroy_count, "dispatcher.timer.destroy")

static void timer_irq_callback(Timer* timer, zx_time_t now, void* arg) {
  // We are in IRQ context and cannot touch the timer state_tracker, so we
  // schedule a DPC to do so. TODO(cpu): figure out ways to reduce the lag.
  auto dpc = reinterpret_cast<Dpc*>(arg);
  dpc->Queue(true);
}

static void dpc_callback(Dpc* d) { d->arg<TimerDispatcher>()->OnTimerFired(); }

zx_status_t TimerDispatcher::Create(uint32_t options, KernelHandle<TimerDispatcher>* handle,
                                    zx_rights_t* rights) {
  if (options > ZX_TIMER_SLACK_LATE)
    return ZX_ERR_INVALID_ARGS;

  switch (options) {
    case ZX_TIMER_SLACK_CENTER:
    case ZX_TIMER_SLACK_EARLY:
    case ZX_TIMER_SLACK_LATE:
      break;
    default:
      return ZX_ERR_INVALID_ARGS;
  };

  fbl::AllocChecker ac;
  KernelHandle new_handle(fbl::AdoptRef(new (&ac) TimerDispatcher(options)));
  if (!ac.check())
    return ZX_ERR_NO_MEMORY;

  *rights = default_rights();
  *handle = ktl::move(new_handle);
  return ZX_OK;
}

TimerDispatcher::TimerDispatcher(uint32_t options)
    : options_(options),
      timer_dpc_(&dpc_callback, this),
      deadline_(0u),
      slack_amount_(0u),
      cancel_pending_(false) {
  kcounter_add(dispatcher_timer_create_count, 1);
}

TimerDispatcher::~TimerDispatcher() {
  DEBUG_ASSERT(deadline_ == 0u);
  DEBUG_ASSERT(slack_amount_ == 0u);
  kcounter_add(dispatcher_timer_destroy_count, 1);
}

void TimerDispatcher::on_zero_handles() {
  // The timers can be kept alive indefinitely by the callbacks, so
  // we need to cancel when there are no more user-mode clients.
  Guard<Mutex> guard{get_lock()};

  // We must ensure that the timer callback (running in interrupt context,
  // possibly on a different CPU) has completed before possibly destroy
  // the timer.  So cancel the timer if we haven't already.
  if (!CancelTimerLocked())
    timer_.Cancel();
}

zx_status_t TimerDispatcher::Set(zx_time_t deadline, zx_duration_t slack_amount) {
  canary_.Assert();

  Guard<Mutex> guard{get_lock()};

  bool did_cancel = CancelTimerLocked();

  // If the timer is already due, then we can set the signal immediately without
  // starting the timer.
  if ((deadline == 0u) || (deadline <= current_time())) {
    UpdateStateLocked(0u, ZX_TIMER_SIGNALED);
    return ZX_OK;
  }

  deadline_ = deadline;
  slack_amount_ = slack_amount;

  // If we're imminently awaiting a timer callback due to a prior cancellation request,
  // let the callback take care of restarting the timer too so everything happens in the
  // right sequence.
  if (cancel_pending_)
    return ZX_OK;

  // We need to ref-up because the timer and the dpc don't understand
  // refcounted objects. The Release() is called either in OnTimerFired()
  // or in the complicated cancellation path above.
  AddRef();

  // We must ensure that the timer callback (running in interrupt context,
  // possibly on a different CPU) has completed before set try to set the
  // timer again.  So cancel the timer if we haven't already.
  SetTimerLocked(!did_cancel);

  return ZX_OK;
}

zx_status_t TimerDispatcher::Cancel() {
  canary_.Assert();
  Guard<Mutex> guard{get_lock()};
  CancelTimerLocked();
  return ZX_OK;
}

void TimerDispatcher::SetTimerLocked(bool cancel_first) {
  if (cancel_first)
    timer_.Cancel();

  slack_mode slack_mode = TIMER_SLACK_CENTER;

  switch (options_) {
    case ZX_TIMER_SLACK_CENTER:
      slack_mode = TIMER_SLACK_CENTER;
      break;
    case ZX_TIMER_SLACK_EARLY:
      slack_mode = TIMER_SLACK_EARLY;
      break;
    case ZX_TIMER_SLACK_LATE:
      slack_mode = TIMER_SLACK_LATE;
      break;
    default:
      panic("Unknown options: %x", options_);
  };

  const TimerSlack slack{slack_amount_, slack_mode};
  const Deadline slackDeadline(deadline_, slack);
  timer_.Set(slackDeadline, &timer_irq_callback, &timer_dpc_);
}

bool TimerDispatcher::CancelTimerLocked() {
  // Always clear the signal bit.
  UpdateStateLocked(ZX_TIMER_SIGNALED, 0u);

  // If the timer isn't pending then we're done.
  if (!deadline_)
    return false;  // didn't call timer_cancel
  deadline_ = 0u;
  slack_amount_ = 0;

  // If we're already waiting for the timer to be canceled, then we don't need
  // to cancel it again.
  if (cancel_pending_)
    return false;  // didn't call timer_cancel

  // The timer is active and needs to be canceled.
  // Refcount is at least 2 because there is a pending timer that we need to cancel.
  bool timer_canceled = timer_.Cancel();
  if (timer_canceled) {
    // Managed to cancel before OnTimerFired() ran. So we need to decrement the
    // ref count here.
    ASSERT(!Release());
  } else {
    // The DPC thread is about to run the callback! Yet we are holding the lock.
    // We'll let the timer callback take care of cleanup.
    cancel_pending_ = true;
  }
  return true;  // did call timer_cancel
}

void TimerDispatcher::OnTimerFired() {
  canary_.Assert();

  {
    Guard<Mutex> guard{get_lock()};

    if (cancel_pending_) {
      // We previously attempted to cancel the timer but the dpc had already
      // been queued.  Suppress handling of this callback but take care to
      // restart the timer if its deadline was set in the meantime.
      cancel_pending_ = false;
      if (deadline_ != 0u) {
        // We must ensure that the timer callback (running in interrupt context,
        // possibly on a different CPU) has completed before set try to set the
        // timer again.
        SetTimerLocked(true /* cancel first*/);
        return;
      }
    } else {
      // The timer is firing.
      UpdateStateLocked(0u, ZX_TIMER_SIGNALED);
      deadline_ = 0u;
      slack_amount_ = 0u;
    }
  }

  // Drop the RefCounted reference that was added in Set(). If this was the
  // last reference, the RefCounted contract requires that we delete
  // ourselves.
  if (Release())
    delete this;
}

void TimerDispatcher::GetInfo(zx_info_timer_t* info) const {
  canary_.Assert();

  Guard<Mutex> guard{get_lock()};
  info->options = options_;
  info->deadline = deadline_;
  info->slack = slack_amount_;
}
