// Copyright 2021 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_VM_INCLUDE_VM_STACK_OWNED_LOANED_PAGES_INTERVAL_H_
#define ZIRCON_KERNEL_VM_INCLUDE_VM_STACK_OWNED_LOANED_PAGES_INTERVAL_H_

#include <kernel/owned_wait_queue.h>
#include <kernel/thread.h>
#include <ktl/optional.h>

struct vm_page;

// This class establishes a RAII style code interval (while an instance of this class is on the
// stack).  During this interval, it is permissible to stack-own a loaned page.
//
// Intervals are allowed to nest.  The outermost interval (technically: first constructed) is the
// interval that applies.
//
// A thread that wants to wait for a loaned page to no longer be stack-owned can call
// WaitUntilContiguousPageNotStackOwned().  The wait will participate in priority inheritance which
// will boost the stack-owning thread to at least the priority of the waiting thread for the
// duration of the wait.
//
// At least for now, instances of this class are only meant to exist on the stack.  Heap allocation
// of an instance of this class is not currently supported, and will fail asserts if the destruction
// thread doesn't match the construction thread (and possibly other asserts).
class StackOwnedLoanedPagesInterval {
 public:
  // No copy or move.
  StackOwnedLoanedPagesInterval(const StackOwnedLoanedPagesInterval& to_copy) = delete;
  StackOwnedLoanedPagesInterval& operator=(const StackOwnedLoanedPagesInterval& to_copy) = delete;
  StackOwnedLoanedPagesInterval(StackOwnedLoanedPagesInterval&& to_move) = delete;
  StackOwnedLoanedPagesInterval& operator=(StackOwnedLoanedPagesInterval&& to_move) = delete;

  StackOwnedLoanedPagesInterval() {
    Thread* current_thread = Thread::Current::Get();
    // outermost interval wins; inner intervals don't do much
    if (unlikely(current_thread->stack_owned_loaned_pages_interval_)) {
      // Strictly speaking we don't need this assignment, but go ahead and set to nullptr in this
      // unlikely path, for the benefit of asserts in the destructor.
      owning_thread_ = nullptr;
      return;
    }
    // We delay AssignOnwer(current_thread) until PrepareForWaiter(), since often there will be no
    // waiter.
    owning_thread_ = current_thread;
    current_thread->stack_owned_loaned_pages_interval_ = this;
  }

  ~StackOwnedLoanedPagesInterval() {
    canary_.Assert();
    Thread* current_thread = Thread::Current::Get();
    // only remove if this is the outermost interval, which is likely
    if (likely(current_thread->stack_owned_loaned_pages_interval_ == this)) {
      DEBUG_ASSERT(owning_thread_);
      DEBUG_ASSERT(owning_thread_ == current_thread);
      current_thread->stack_owned_loaned_pages_interval_ = nullptr;
      if (unlikely(is_ready_for_waiter_.load(ktl::memory_order_acquire))) {
        // In the much more rare case that there are any waiters, wake all waiters and clear out the
        // owner before destructing owned_wait_queue_.  We do this out-of-line since it's not the
        // common path.
        WakeWaitersAndClearOwner(current_thread);
      }
      // PrepareForWaiter() was never called, so no need to acquire thread_lock.  This is very
      // likely.  Done.
    }
  }

  static StackOwnedLoanedPagesInterval& current();
  static StackOwnedLoanedPagesInterval* maybe_current();

  static void WaitUntilContiguousPageNotStackOwned(vm_page* page) TA_EXCL(thread_lock);

 private:
  // This sets up to permit a waiter, and asserts that the calling thread is not the constructing
  // thread, since waiting by the constructing/destructing thread would block (or maybe fail).
  void PrepareForWaiter() TA_REQ(thread_lock, preempt_disabled_token);

  void WakeWaitersAndClearOwner(Thread* current_thread) TA_EXCL(thread_lock);

  // magic value
  fbl::Canary<fbl::magic("SOPI")> canary_;
  // We stash the owning thread as part of delaying OwnedWaitQueue::AssignOwner(), to avoid putting
  // unnecessary pressure on thread_lock when there's no waiter.
  //
  // Only set during the constructor.  Only read after that.  Intentionally not initialized here to
  // avoid redundant initialization.
  Thread* owning_thread_;
  // This is atomic because in the common case of no waiter, the OwnedWaitQueue
  // isn't created and the
  // This is atomic because in the common case of no waiter, the thread with
  // StackOwnedLoanedPagesInterval on its stack doesn't need to acquire the thread_lock to read
  // false from here during destruction (and so never needs to acquire thread_lock).
  ktl::atomic<bool> is_ready_for_waiter_{false};
  // In the common case of no waiter, this never gets constructed or destructed.  We only construct
  // this on PrepareForWaiter() during WaitUntilContiguousPageNotStackOwned().
  ktl::optional<OwnedWaitQueue> owned_wait_queue_;
};

#endif  // ZIRCON_KERNEL_VM_INCLUDE_VM_STACK_OWNED_LOANED_PAGES_INTERVAL_H_
