// 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();
}

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_;
}
