// Copyright 2019 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

#ifndef ZIRCON_KERNEL_INCLUDE_KERNEL_WAIT_QUEUE_INTERNAL_H_
#define ZIRCON_KERNEL_INCLUDE_KERNEL_WAIT_QUEUE_INTERNAL_H_

#include <lib/ktrace.h>
#include <platform.h>
#include <zircon/errors.h>

#include <kernel/scheduler.h>
#include <kernel/thread.h>
#include <kernel/wait.h>

// Notes for WaitQueue::BlockEtcPreamble and BlockEtcPostamble.
//
// Currently, there are two variants of WaitQueues in Zircon.  The standard
// WaitQueue (used for most tasks) and the specialized
// OwnedWaitQueues (used for mutexes/futexes/brwlocks, and anything else which
// needs to have a concept of priority inheritance).
//
// The "Block" operation for these two versions are _almost_ identical.  The
// only real difference between the two is that the OWQ implementation needs to
// stop after we have decided that we are actually going to block the thread,
// but before the timeout timer is armed and the thread is actually blocked, in
// order to update it's PI chain bookkeeping.
//
// Instead of duplicating the code, or exposing a code-injection
// mechanism into the public API, we split the code into two private
// inline member functions that we hide in instead.  The first
// (BlockEtcPreamble) performs all of the checks and bookkeeping up-to
// the point of arming the timer and blocking, the second
// (BlockEtcPostamble) finishes the job.
//
// The traditional WaitQueue implementation of
// WaitQueue::BlockEtc just calls these two functions back to back, relying on
// the inlining to generate the original function.  The OwnedWaitQueue
// implementation does the same, but injects its bookkeeping at the appropriate
// point.
//
// Nothing but these two specific pieces of code should *ever* need to
// call these functions.  Users should *always* be using either
// WaitQueue::BlockEtc/Block, or OwnedWaitQueue::BlockAndAssignOwner
// instead.
//
inline zx_status_t WaitQueue::BlockEtcPreamble(const Deadline& deadline, uint signal_mask,
                                               ResourceOwnership reason,
                                               Interruptible interruptible) TA_REQ(thread_lock) {
  Thread* current_thread = Thread::Current::Get();

  if (deadline.when() != ZX_TIME_INFINITE && deadline.when() <= current_time()) {
    return ZX_ERR_TIMED_OUT;
  }

  if (interruptible == Interruptible::Yes && (unlikely(current_thread->signals() & ~signal_mask))) {
    zx_status_t status = current_thread->CheckKillOrSuspendSignal();
    if (status != ZX_OK) {
      return status;
    }
  }

  WaitQueueCollection::ThreadState& state = current_thread->wait_queue_state();

  state.interruptible_ = interruptible;

  collection_.Insert(current_thread);
  if (reason == ResourceOwnership::Normal) {
    current_thread->set_blocked();
  } else {
    current_thread->set_blocked_read_lock();
  }
  state.blocking_wait_queue_ = this;
  state.blocked_status_ = ZX_OK;

  return ZX_OK;
}

inline zx_status_t WaitQueue::BlockEtcPostamble(const Deadline& deadline) TA_REQ(thread_lock) {
  Thread* current_thread = Thread::Current::Get();
  Timer timer;

  // if the deadline is nonzero or noninfinite, set a callback to yank us out of the queue
  if (deadline.when() != ZX_TIME_INFINITE) {
    timer.Set(deadline, &WaitQueue::TimeoutHandler, (void*)current_thread);
  }

  ktrace_ptr(TAG_KWAIT_BLOCK, this, 0, 0);

  Scheduler::Block();

  ktrace_ptr(TAG_KWAIT_UNBLOCK, this, current_thread->wait_queue_state().blocked_status_, 0);

  // we don't really know if the timer fired or not, so it's better safe to try to cancel it
  if (deadline.when() != ZX_TIME_INFINITE) {
    timer.Cancel();
  }

  current_thread->wait_queue_state().interruptible_ = Interruptible::No;

  return current_thread->wait_queue_state().blocked_status_;
}

#endif  // ZIRCON_KERNEL_INCLUDE_KERNEL_WAIT_QUEUE_INTERNAL_H_
