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

#include <lib/fit/defer.h>
#include <lib/fit/function.h>
#include <lib/unittest/unittest.h>
#include <lib/zircon-internal/macros.h>
#include <platform.h>
#include <zircon/types.h>

#include <new>

#include <fbl/alloc_checker.h>
#include <fbl/macros.h>
#include <kernel/auto_preempt_disabler.h>
#include <kernel/owned_wait_queue.h>
#include <kernel/scheduler.h>
#include <kernel/thread.h>
#include <kernel/wait.h>
#include <ktl/algorithm.h>
#include <ktl/array.h>
#include <ktl/atomic.h>
#include <ktl/iterator.h>
#include <ktl/limits.h>
#include <ktl/type_traits.h>
#include <ktl/unique_ptr.h>

#include "tests.h"

#include <ktl/enforce.h>

namespace {

constexpr int TEST_LOWEST_PRIORITY = LOWEST_PRIORITY + 1;
constexpr int TEST_HIGHEST_PRIORITY = HIGHEST_PRIORITY;
constexpr int TEST_DEFAULT_PRIORITY = DEFAULT_PRIORITY;
constexpr int TEST_PRIORTY_COUNT = TEST_HIGHEST_PRIORITY - TEST_LOWEST_PRIORITY;

class TestThread;  // fwd decl

// An RAII style helper which lets us auto boost the priority of our test thread
// to maximum, but return it to whatever it was when the test ends.  Many of
// these tests need to rely on timing in order to control the order with which
// threads time out of various wait queues.  Since we don't have deterministic
// control over timing in our tests, we rely on our high priority test thread
// being scheduled and pre-empting all other threads when it's timer goes off in
// order to reduce the chances of timing related flake in the tests.
class AutoPrioBooster {
 public:
  AutoPrioBooster() {
    Thread* t = Thread::Current::Get();
    initial_base_prio_ = t->scheduler_state().base_priority();
    t->SetPriority(TEST_HIGHEST_PRIORITY);
  }

  ~AutoPrioBooster() { Thread::Current::Get()->SetPriority(initial_base_prio_); }

  DISALLOW_COPY_ASSIGN_AND_MOVE(AutoPrioBooster);

 private:
  int initial_base_prio_;
};

// A small helper which creates diffierent distributions of numbers which can be
// used for things like determining priority order, or release order, for the
// various tests.
struct DistroSpec {
  enum class Type { ASCENDING, DESCENDING, SAME, RANDOM, SHUFFLE };

  constexpr DistroSpec(Type t, uint32_t o, uint64_t s = 0) : type(t), offset(o), seed(s) {}

  const Type type;
  const uint32_t offset;
  const uint64_t seed;
};

void CreateDistribution(uint32_t* data, uint32_t N, const DistroSpec& spec) {
  DEBUG_ASSERT(data);
  uint64_t prng = spec.seed;

  switch (spec.type) {
    // Create an ascending sequence from [0, N] offset by spec.offset
    case DistroSpec::Type::ASCENDING:
      for (uint32_t i = 0; i < N; ++i) {
        data[i] = i + spec.offset;
      }
      break;

    // Create a descending sequence from (N, 0] offset by spec.offset
    case DistroSpec::Type::DESCENDING:
      for (uint32_t i = 0; i < N; ++i) {
        data[i] = static_cast<uint32_t>(N - i - 1 + spec.offset);
      }
      break;

    // Set all of the values to just offset.
    case DistroSpec::Type::SAME:
      for (uint32_t i = 0; i < N; ++i) {
        data[i] = spec.offset;
      }
      break;

    // Set all of the values to a random number on the range [0, N) + offset
    case DistroSpec::Type::RANDOM:
      for (uint32_t i = 0; i < N; ++i) {
        data[i] = spec.offset + (rand_r(&prng) % N);
      }
      break;

    // Create a range of values from [0, N) + offset, but shuffle the order of
    // those values in the set.
    case DistroSpec::Type::SHUFFLE:
      // Start by filling our array with a illegal sentinel value (N will do
      // the job just fine), then foreach i in the range [0, num_links) pick a
      // random position in the output to put i, and linearly probe until we
      // find the first unused position in order to shuffle.  Finally, offset
      // by 'offset' and we should be done.
      for (uint32_t i = 0; i < N; ++i) {
        data[i] = N;
      }

      for (uint32_t i = 0; i < N; ++i) {
        uint32_t pos = (rand_r(&prng) % N);
        while (data[pos] != N) {
          pos = (pos + 1) % N;
        }
        data[pos] = i;
      }

      for (uint32_t i = 0; i < N; ++i) {
        data[i] += spec.offset;
      }
      break;
  }
}

template <typename DATA_TYPE, size_t N>
void CreateDistribution(DATA_TYPE (&data)[N], const DistroSpec& spec) {
  static_assert(ktl::is_same<DATA_TYPE, int32_t>::value || ktl::is_same<DATA_TYPE, uint32_t>::value,
                "CreateDistribution only operates on 32 bit integer types!");
  static_assert(N <= ktl::numeric_limits<uint32_t>::max(),
                "CreateDistribution array size must be expressible using a 32 bit unsigned int");
  CreateDistribution(reinterpret_cast<uint32_t*>(data), static_cast<uint32_t>(N), spec);
}

// A simple barrier class which can be waited on by multiple threads.  Used to
// stall test threads at various parts of their execution in order to sequence
// things in a deterministic fashion.
class Barrier {
 public:
  constexpr Barrier(bool signaled = false) : signaled_{signaled} {}
  ~Barrier() {
    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    ASSERT(queue_.IsEmpty());
  }

  void Signal(bool state) {
    bool expected = !state;
    if (signaled_.compare_exchange_strong(expected, state) && state) {
      Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
      queue_.WakeAll(ZX_OK);
    }
  }

  void Wait(Deadline deadline = Deadline::infinite()) {
    if (state()) {
      return;
    }

    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    if (state()) {
      return;
    }

    queue_.Block(deadline, Interruptible::Yes);
  }

  bool state() const { return signaled_.load(); }

 private:
  ktl::atomic<bool> signaled_;
  WaitQueue queue_;
};

// Helper wrapper for an owned wait queue which manages grabbing and releasing
// the thread lock at appropriate times for us.  Mostly, this is just about
// saving some typing.
class LockedOwnedWaitQueue : public OwnedWaitQueue {
 public:
  constexpr LockedOwnedWaitQueue() = default;
  DISALLOW_COPY_ASSIGN_AND_MOVE(LockedOwnedWaitQueue);

  void ReleaseAllThreads() TA_EXCL(thread_lock) {
    AnnotatedAutoPreemptDisabler aapd;
    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    OwnedWaitQueue::WakeThreads(ktl::numeric_limits<uint32_t>::max());
  }

  void ReleaseOneThread() TA_EXCL(thread_lock) {
    AnnotatedAutoPreemptDisabler aapd;
    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    auto hook = [](Thread*, void*) { return Hook::Action::SelectAndAssignOwner; };
    OwnedWaitQueue::WakeThreads(1u, {hook, nullptr});
  }

  void AssignOwner(TestThread* thread) TA_EXCL(thread_lock);
};

// LoopIterPrinter
// A small RAII style class which helps us to print out where a loop iterator
// is when a test fails and bails out.  Note: loop iterator types must be
// convertible to int64_t.
template <typename T>
class LoopIterPrinter {
 public:
  constexpr LoopIterPrinter(const char* field_name, T iter_val)
      : field_name_(field_name), iter_val_(iter_val) {}

  ~LoopIterPrinter() {
    if (field_name_ != nullptr) {
      printf("Test failed with %s == %ld\n", field_name_, static_cast<int64_t>(iter_val_));
    }
  }

  DISALLOW_COPY_ASSIGN_AND_MOVE(LoopIterPrinter);

  void cancel() { field_name_ = nullptr; }

 private:
  const char* field_name_;
  T iter_val_;
};

#define PRINT_LOOP_ITER(_var_name) LoopIterPrinter print_##_var_name(#_var_name, _var_name)

// The core test thread object.  We use this object to build various graphs of
// priority inheritance chains, and then evaluate that the effective priorities
// of the threads involved in the graph are what we expect them to be after
// various mutations of the graph have taken place.
class TestThread {
 public:
  enum class State : uint32_t {
    INITIAL,
    CREATED,
    WAITING_TO_START,
    STARTED,
    WAITING_FOR_SHUTDOWN,
    SHUTDOWN,
  };

  enum class Condition : uint32_t {
    BLOCKED,
    WAITING_FOR_SHUTDOWN,
  };

  TestThread() = default;
  ~TestThread() { Reset(); }

  DISALLOW_COPY_ASSIGN_AND_MOVE(TestThread);

  // Reset the barrier at the start of a test in order to prevent threads from
  // exiting after they have completed their operation..
  static void ResetShutdownBarrier() { allow_shutdown_.Signal(false); }

  // Clear the barrier and allow shutdown.
  static void ClearShutdownBarrier() { allow_shutdown_.Signal(true); }

  static Barrier& allow_shutdown() { return allow_shutdown_; }

  // Create a thread, settings its entry point and initial base priority in
  // the process, but do not start it yet.
  bool Create(int initial_base_priority);

  // Start the thread, have it do nothing but wait to be allowed to exit.
  bool DoStall();

  // Start the thread and have it block on an owned wait queue, declaring the
  // specified test thread to be the owner of that queue in the process.
  bool BlockOnOwnedQueue(OwnedWaitQueue* owned_wq, TestThread* owner,
                         Deadline timeout = Deadline::infinite());

  // Directly take ownership of the specified wait queue using AssignOwner.
  bool TakeOwnership(OwnedWaitQueue* owned_wq);

  // Change base the priority of the thread
  bool SetBasePriority(int base_prio) {
    BEGIN_TEST;
    ASSERT_NONNULL(thread_);
    ASSERT_EQ(state(), State::STARTED);
    ASSERT_GE(base_prio, TEST_LOWEST_PRIORITY);
    ASSERT_LT(base_prio, TEST_HIGHEST_PRIORITY);

    thread_->SetPriority(base_prio);

    END_TEST;
  }

  // Reset the thread back to its initial state.  If |explicit_kill| is true,
  // then do not wait for the thread to exit normally if it has been started.
  // Simply send it the kill signal.
  bool Reset(bool explicit_kill = false);

  int inherited_priority() const {
    if (thread_ == nullptr) {
      return -2;
    }

    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    return thread_->scheduler_state().inherited_priority();
  }

  int effective_priority() const {
    if (thread_ == nullptr) {
      return -2;
    }

    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    return thread_->scheduler_state().effective_priority();
  }

  int base_priority() const {
    if (thread_ == nullptr) {
      return -2;
    }

    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    return thread_->scheduler_state().base_priority();
  }

  State state() const { return state_.load(); }

  thread_state tstate() const {
    if (thread_ == nullptr) {
      return thread_state::THREAD_DEATH;
    }

    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    return thread_->state();
  }

  template <Condition condition>
  bool WaitFor();

 private:
  // Test threads in the various tests use lambdas in order to store their
  // customized test operations.  In order to allow these lambda's to capture
  // context from their local scope, but not need to use the heap in order to
  // allocate the storage for the scope, we need to know the worst case
  // capture storage requirements across all of these tests.  Armed with this
  // knowledge, we can use a fit::inline_function to pre-allocate storage in
  // the TestThread object for the worst case lambda we will encounter in the
  // test suite.
  //
  // Currently, this bound is 6 pointer's worth of storage.  If this grows in
  // the future, this constexpr bound should be updated to match the new worst
  // case storage requirement.
  static constexpr size_t kMaxOpLambdaCaptureStorageBytes = sizeof(void*) * 6;

  friend class LockedOwnedWaitQueue;

  int ThreadEntry();

  static Barrier allow_shutdown_;

  Thread* thread_ = nullptr;
  ktl::atomic<State> state_{State::INITIAL};
  fit::inline_function<void(void), kMaxOpLambdaCaptureStorageBytes> op_;
};

Barrier TestThread::allow_shutdown_;

bool TestThread::Create(int initial_base_priority) {
  BEGIN_TEST;

  ASSERT_NULL(thread_);
  ASSERT_EQ(state(), State::INITIAL);
  ASSERT_GE(initial_base_priority, TEST_LOWEST_PRIORITY);
  ASSERT_LT(initial_base_priority, TEST_HIGHEST_PRIORITY);

  thread_ = Thread::Create(
      "pi_test_thread",
      [](void* ctx) -> int { return reinterpret_cast<TestThread*>(ctx)->ThreadEntry(); },
      reinterpret_cast<void*>(this), initial_base_priority);

  ASSERT_NONNULL(thread_);

  state_.store(State::CREATED);

  END_TEST;
}

bool TestThread::DoStall() {
  BEGIN_TEST;
  ASSERT_EQ(state(), State::CREATED);
  ASSERT_FALSE(static_cast<bool>(op_));

  op_ = []() {};

  state_.store(State::WAITING_TO_START);
  thread_->Resume();

  ASSERT_TRUE(WaitFor<Condition::BLOCKED>());

  END_TEST;
}

bool TestThread::BlockOnOwnedQueue(OwnedWaitQueue* owned_wq, TestThread* owner, Deadline timeout) {
  BEGIN_TEST;
  ASSERT_EQ(state(), State::CREATED);
  ASSERT_FALSE(static_cast<bool>(op_));

  op_ = [owned_wq, owner_thrd = owner ? owner->thread_ : nullptr, timeout]() {
    AnnotatedAutoPreemptDisabler aapd;
    Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
    owned_wq->BlockAndAssignOwner(timeout, owner_thrd, ResourceOwnership::Normal,
                                  Interruptible::Yes);
  };

  state_.store(State::WAITING_TO_START);
  thread_->Resume();

  ASSERT_TRUE(WaitFor<Condition::BLOCKED>());

  END_TEST;
}

bool TestThread::Reset(bool explicit_kill) {
  BEGIN_TEST;

  // If we are explicitly killing the thread as part of the test, then we
  // should not expect the shutdown barrier to be cleared.
  if (!explicit_kill) {
    EXPECT_TRUE(allow_shutdown_.state());
  }

  constexpr zx_duration_t join_timeout = ZX_MSEC(500);

  switch (state()) {
    case State::INITIAL:
      break;
    case State::CREATED:
      // Created but not started?  thread_forget seems to be the proper way to
      // cleanup a thread which was never started.
      ASSERT(thread_ != nullptr);
      thread_->Forget();
      thread_ = nullptr;
      break;

    case State::WAITING_TO_START:
    case State::STARTED:
    case State::WAITING_FOR_SHUTDOWN:
    case State::SHUTDOWN:
      // If we are explicitly killing the thread, send it the kill signal now.
      if (explicit_kill) {
        thread_->Kill();
      }

      // Hopefully, the thread is on it's way to termination as we speak.
      // Attempt to join it.  If this fails, print a warning and then kill it.
      ASSERT(thread_ != nullptr);
      int ret_code;
      zx_status_t res = thread_->Join(&ret_code, current_time() + join_timeout);
      if (res != ZX_OK) {
        printf("Failed to join thread %p (res %d); attempting to kill\n", thread_, res);

        // If we have already sent the kill signal to the thread and failed,
        // there is no point in trying to do so gain.
        if (!explicit_kill) {
          thread_->Kill();
          res = thread_->Join(&ret_code, current_time() + join_timeout);
        }

        if (res != ZX_OK) {
          panic("Failed to stop thread during PI tests!! (res = %d)\n", res);
        }
      }
      thread_ = nullptr;
  }

  state_.store(State::INITIAL);
  op_ = nullptr;
  ASSERT_NULL(thread_);

  END_TEST;
}

int TestThread::ThreadEntry() {
  if (!static_cast<bool>(op_) || (state() != State::WAITING_TO_START)) {
    return -1;
  }

  state_.store(State::STARTED);
  op_();
  state_.store(State::WAITING_FOR_SHUTDOWN);
  allow_shutdown_.Wait();

  state_.store(State::SHUTDOWN);
  op_ = nullptr;

  return 0;
}

template <TestThread::Condition condition>
bool TestThread::WaitFor() {
  BEGIN_TEST;

  constexpr zx_duration_t timeout = ZX_SEC(10);
  constexpr zx_duration_t poll_interval = ZX_USEC(100);
  zx_time_t deadline = current_time() + timeout;

  while (true) {
    if constexpr (condition == Condition::BLOCKED) {
      thread_state cur_state = tstate();

      if (cur_state == THREAD_BLOCKED) {
        break;
      }

      if (cur_state != THREAD_RUNNING) {
        ASSERT_EQ(THREAD_READY, cur_state);
      }
    } else {
      static_assert(condition == Condition::WAITING_FOR_SHUTDOWN);
      if (state() == State::WAITING_FOR_SHUTDOWN) {
        break;
      }
    }

    zx_time_t now = current_time();
    ASSERT_LT(now, deadline);
    Thread::Current::SleepRelative(poll_interval);
  }

  END_TEST;
}

void LockedOwnedWaitQueue::AssignOwner(TestThread* thread) {
  AnnotatedAutoPreemptDisabler aapd;
  Guard<MonitoredSpinLock, IrqSave> guard{ThreadLock::Get(), SOURCE_TAG};
  OwnedWaitQueue::AssignOwner(thread ? thread->thread_ : nullptr);
}

bool pi_test_basic() {
  BEGIN_TEST;

  enum class ReleaseMethod { WAKE = 0, TIMEOUT, KILL };

  AutoPrioBooster pboost;
  constexpr zx_duration_t TIMEOUT_RELEASE_DURATION = ZX_MSEC(200);
  constexpr int END_PRIO = TEST_DEFAULT_PRIORITY;
  constexpr int PRIO_DELTAS[] = {-1, 0, 1};
  constexpr ReleaseMethod REL_METHODS[] = {ReleaseMethod::WAKE, ReleaseMethod::TIMEOUT,
                                           ReleaseMethod::KILL};

  for (auto prio_delta : PRIO_DELTAS) {
    for (auto rel_method : REL_METHODS) {
      PRINT_LOOP_ITER(prio_delta);
      PRINT_LOOP_ITER(rel_method);

      bool retry_test;
      do {
        retry_test = false;

        LockedOwnedWaitQueue owq;
        TestThread pressure_thread;
        TestThread blocking_thread;

        auto cleanup = fit::defer([&]() {
          TestThread::ClearShutdownBarrier();
          owq.ReleaseAllThreads();
          pressure_thread.Reset();
          blocking_thread.Reset();
        });

        int pressure_prio = END_PRIO + prio_delta;
        int expected_prio = (prio_delta > 0) ? pressure_prio : END_PRIO;

        // Make sure that our default barriers have been reset to their proper
        // initial states.
        TestThread::ResetShutdownBarrier();

        // Create 2 threads, one which will sit at the end of the priority
        // chain, and one which will exert priority pressure on the end of the
        // chain.
        ASSERT_TRUE(blocking_thread.Create(END_PRIO));
        ASSERT_TRUE(pressure_thread.Create(pressure_prio));

        // Start the first thread, wait for it to block, and verify that it's
        // priority is correct (it should not be changed).
        ASSERT_TRUE(blocking_thread.DoStall());
        ASSERT_EQ(TEST_DEFAULT_PRIORITY, blocking_thread.effective_priority());

        // Start the second thread, and have it block on the owned wait queue,
        // and declare the blocking thread to be the owner of the queue at the
        // same time.  Then check to be sure that the effective priority of the
        // blocking thread matches what we expect to see.
        Deadline timeout = (rel_method == ReleaseMethod::TIMEOUT)
                               ? Deadline::after(TIMEOUT_RELEASE_DURATION)
                               : Deadline::infinite();
        ASSERT_TRUE(pressure_thread.BlockOnOwnedQueue(&owq, &blocking_thread, timeout));

        // Observe the effective priority of the blocking thread, then observe
        // the state of the thread applying pressure.  If this is the TIMEOUT
        // test, the thread *must* still be blocked on |owq| (not timed out yet)
        // in order for the test to be considered valid.  If the thread managed
        // to unblock before we could observe its effective priority, just try
        // again.
        int observed_priority = blocking_thread.effective_priority();
        if (rel_method == ReleaseMethod::TIMEOUT) {
          retry_test = (pressure_thread.tstate() != thread_state::THREAD_BLOCKED) ||
                       (pressure_thread.state() == TestThread::State::WAITING_FOR_SHUTDOWN);
        }

        // Only assert this if we managed to observe the blocked thread's
        // effective priority while the pressure thread was still applying
        // pressure.
        if (!retry_test) {
          ASSERT_EQ(expected_prio, observed_priority);
        }

        // Finally, release the thread from the owned wait queue based on
        // the release method we are testing.  We will either explicitly
        // wake it up, let it time out, or kill the thread outright.
        //
        // Then, verify that the priority drops back down to what we
        // expected.
        switch (rel_method) {
          case ReleaseMethod::WAKE:
            owq.ReleaseAllThreads();
            break;

          case ReleaseMethod::TIMEOUT:
            // Wait until the pressure thread times out and has exited.
            ASSERT_TRUE(pressure_thread.WaitFor<TestThread::Condition::WAITING_FOR_SHUTDOWN>());
            break;

          case ReleaseMethod::KILL:
            pressure_thread.Reset(true);
            break;
        }
        ASSERT_EQ(TEST_DEFAULT_PRIORITY, blocking_thread.effective_priority());
      } while (retry_test);

      print_prio_delta.cancel();
      print_rel_method.cancel();
    }
  }

  END_TEST;
}

bool pi_test_changing_priority() {
  BEGIN_TEST;

  AutoPrioBooster pboost;
  LockedOwnedWaitQueue owq;
  TestThread pressure_thread;
  TestThread blocking_thread;

  auto cleanup = fit::defer([&]() {
    TestThread::ClearShutdownBarrier();
    owq.ReleaseAllThreads();
    pressure_thread.Reset();
    blocking_thread.Reset();
  });

  // Make sure that our default barriers have been reset to their proper
  // initial states.
  TestThread::ResetShutdownBarrier();

  // Create our threads.
  ASSERT_TRUE(blocking_thread.Create(TEST_DEFAULT_PRIORITY));
  ASSERT_TRUE(pressure_thread.Create(TEST_LOWEST_PRIORITY));

  // Start the first thread, wait for it to block, and verify that it's
  // priority is correct (it should not be changed).
  ASSERT_TRUE(blocking_thread.DoStall());
  ASSERT_EQ(TEST_DEFAULT_PRIORITY, blocking_thread.effective_priority());

  // Block the second thread behind the first.
  ASSERT_TRUE(pressure_thread.BlockOnOwnedQueue(&owq, &blocking_thread));
  ASSERT_EQ(TEST_DEFAULT_PRIORITY, blocking_thread.effective_priority());

  // Run up and down through a bunch of priorities
  for (int ascending = TEST_LOWEST_PRIORITY; ascending < TEST_HIGHEST_PRIORITY; ++ascending) {
    PRINT_LOOP_ITER(ascending);
    int expected = ktl::max(ascending, TEST_DEFAULT_PRIORITY);
    ASSERT_TRUE(pressure_thread.SetBasePriority(ascending));
    ASSERT_EQ(expected, blocking_thread.effective_priority());
    print_ascending.cancel();
  }

  for (int descending = TEST_HIGHEST_PRIORITY - 1; descending >= TEST_LOWEST_PRIORITY;
       --descending) {
    PRINT_LOOP_ITER(descending);
    int expected = ktl::max(descending, TEST_DEFAULT_PRIORITY);
    ASSERT_TRUE(pressure_thread.SetBasePriority(descending));
    ASSERT_EQ(expected, blocking_thread.effective_priority());
    print_descending.cancel();
  }

  // Release the pressure thread, validate that the priority is what we
  // started with and we are done.
  owq.ReleaseAllThreads();
  ASSERT_EQ(TEST_DEFAULT_PRIORITY, blocking_thread.effective_priority());

  END_TEST;
}

template <uint32_t CHAIN_LEN>
bool pi_test_chain() {
  static_assert(CHAIN_LEN >= 2, "Must have at least 2 nodes to form a PI chain");
  static_assert(CHAIN_LEN < TEST_PRIORTY_COUNT,
                "Cannot create a chain which would result in a thread being created at "
                "TEST_HIGHEST_PRIORITY");

  BEGIN_TEST;
  fbl::AllocChecker ac;

  enum class ReleaseOrder : uint64_t { ASCENDING = 0, DESCENDING };

  AutoPrioBooster pboost;
  TestThread threads[CHAIN_LEN];
  struct Link {
    LockedOwnedWaitQueue queue;
    bool active = false;
  };
  auto links = ktl::make_unique<ktl::array<Link, CHAIN_LEN - 1>>(&ac);
  ASSERT_TRUE(ac.check());

  const DistroSpec PRIORITY_GENERATORS[] = {
      {DistroSpec::Type::ASCENDING, TEST_LOWEST_PRIORITY},
      {DistroSpec::Type::DESCENDING, TEST_LOWEST_PRIORITY},
      {DistroSpec::Type::SAME, TEST_DEFAULT_PRIORITY},
      {DistroSpec::Type::RANDOM, TEST_LOWEST_PRIORITY, 0xa064eba4bf1b5087},
      {DistroSpec::Type::RANDOM, TEST_LOWEST_PRIORITY, 0x87251211471cb789},
      {DistroSpec::Type::SHUFFLE, TEST_LOWEST_PRIORITY, 0xbd6f3bfe33d51c8e},
      {DistroSpec::Type::SHUFFLE, TEST_LOWEST_PRIORITY, 0x857ce1aa3209ecc7},
  };

  const DistroSpec RELEASE_ORDERS[]{
      {DistroSpec::Type::ASCENDING, 0},
      {DistroSpec::Type::DESCENDING, 0},
      {DistroSpec::Type::SHUFFLE, 0, 0xac8d4a8ed016caf0},
      {DistroSpec::Type::SHUFFLE, 0, 0xb51e76ca5cf20875},
  };

  for (uint32_t pgen_ndx = 0; pgen_ndx < ktl::size(PRIORITY_GENERATORS); ++pgen_ndx) {
    PRINT_LOOP_ITER(pgen_ndx);

    // Generate the priority map for this pass.
    int prio_map[ktl::size(threads)];
    CreateDistribution(prio_map, PRIORITY_GENERATORS[pgen_ndx]);

    for (uint32_t ro_ndx = 0; ro_ndx < ktl::size(RELEASE_ORDERS); ++ro_ndx) {
      PRINT_LOOP_ITER(ro_ndx);

      // Generate the order in which we will release the links for this
      // pass
      uint32_t release_ordering[CHAIN_LEN - 1];
      CreateDistribution(release_ordering, RELEASE_ORDERS[ro_ndx]);

      auto cleanup = fit::defer([&]() {
        TestThread::ClearShutdownBarrier();
        for (auto& l : *links) {
          l.queue.ReleaseAllThreads();
        }
        for (auto& t : threads) {
          t.Reset();
        }
      });

      // Lambda used to validate the current thread priorities.
      auto ValidatePriorities = [&]() -> bool {
        BEGIN_TEST;

        int expected_prio = -1;

        for (uint32_t tndx = ktl::size(threads); tndx-- > 0;) {
          PRINT_LOOP_ITER(tndx);

          // All threads should either be created, started or waiting for
          // shutdown.  If they are merely created, they have no effective
          // priority to evaluate at the moment, so just skip them.
          const auto& t = threads[tndx];
          const TestThread::State cur_state = t.state();
          if (cur_state == TestThread::State::CREATED) {
            print_tndx.cancel();
            continue;
          }

          if (cur_state != TestThread::State::WAITING_FOR_SHUTDOWN) {
            ASSERT_EQ(TestThread::State::STARTED, cur_state);
          }

          // If the link behind us in the chain does not exist, or exists
          // but is not currently active, then reset the expected priority
          // pressure.  Otherwise, the expected priority should be the
          // priority of the maximum of the base priorities we have
          // traversed so far.
          ASSERT_LT(tndx, ktl::size(prio_map));
          if ((tndx >= links->size()) || !(*links)[tndx].active) {
            expected_prio = prio_map[tndx];
          } else {
            expected_prio = ktl::max(expected_prio, prio_map[tndx]);
          }

          ASSERT_EQ(expected_prio, t.effective_priority());
          print_tndx.cancel();
        }

        END_TEST;
      };

      // Make sure that our default barriers have been reset to their proper
      // initial states.
      TestThread::ResetShutdownBarrier();

      // Create our threads.
      for (uint32_t tndx = 0; tndx < ktl::size(threads); ++tndx) {
        ASSERT_LT(tndx, ktl::size(prio_map));
        PRINT_LOOP_ITER(tndx);
        ASSERT_TRUE(threads[tndx].Create(prio_map[tndx]));
        print_tndx.cancel();
      }

      // Start the head of the chain, wait for it to block, then verify that its
      // priority is correct (it should not be changed).
      auto& chain_head = threads[0];
      ASSERT_TRUE(chain_head.DoStall());
      ASSERT_TRUE(ValidatePriorities());

      // Start each of the threads in the chain one at a time.  Make sure that the
      // pressure of the threads in the chain is properly transmitted each time.
      for (uint32_t tndx = 1; tndx < ktl::size(threads); ++tndx) {
        PRINT_LOOP_ITER(tndx);

        auto& link = (*links)[tndx - 1];
        ASSERT_TRUE(threads[tndx].BlockOnOwnedQueue(&link.queue, &threads[tndx - 1]));
        link.active = true;
        ASSERT_TRUE(ValidatePriorities());

        print_tndx.cancel();
      }

      // Tear down the chain according to the release ordering for this
      // pass.  Make sure that the priority properly relaxes for each of
      // the threads as we do so.
      for (auto link_ndx : release_ordering) {
        PRINT_LOOP_ITER(link_ndx);

        ASSERT_LT(link_ndx, links->size());
        auto& link = (*links)[link_ndx];
        link.queue.ReleaseAllThreads();
        link.active = false;
        ASSERT_TRUE(ValidatePriorities());

        print_link_ndx.cancel();
      }

      print_ro_ndx.cancel();
    }

    print_pgen_ndx.cancel();
  }

  END_TEST;
}

template <uint32_t WAITER_CNT>
bool pi_test_multi_waiter() {
  static_assert(WAITER_CNT >= 2, "Must have at least 2 waiters in the multi-waiter test");
  static_assert(WAITER_CNT < TEST_PRIORTY_COUNT,
                "Multi waiter test must have fewer waiters than priority levels");
  BEGIN_TEST;
  fbl::AllocChecker ac;
  AutoPrioBooster pboost;

  LockedOwnedWaitQueue blocking_queue;
  TestThread blocking_thread;
  struct Waiter {
    TestThread thread;
    bool is_waiting = false;
    int prio = 0;
  };
  auto waiters = ktl::make_unique<ktl::array<Waiter, WAITER_CNT>>(&ac);
  ASSERT_TRUE(ac.check());

  const int BLOCKING_THREAD_PRIO[] = {TEST_LOWEST_PRIORITY, TEST_DEFAULT_PRIORITY,
                                      TEST_HIGHEST_PRIORITY - 1};
  const DistroSpec PRIORITY_GENERATORS[] = {
      {DistroSpec::Type::ASCENDING, TEST_LOWEST_PRIORITY},
      {DistroSpec::Type::DESCENDING, TEST_LOWEST_PRIORITY},
      {DistroSpec::Type::SAME, TEST_DEFAULT_PRIORITY},
      {DistroSpec::Type::RANDOM, TEST_LOWEST_PRIORITY, 0xa064eba4bf1b5087},
      {DistroSpec::Type::RANDOM, TEST_LOWEST_PRIORITY, 0x87251211471cb789},
      {DistroSpec::Type::SHUFFLE, TEST_LOWEST_PRIORITY, 0xbd6f3bfe33d51c8e},
      {DistroSpec::Type::SHUFFLE, TEST_LOWEST_PRIORITY, 0x857ce1aa3209ecc7},
  };

  for (auto bt_prio : BLOCKING_THREAD_PRIO) {
    PRINT_LOOP_ITER(bt_prio);

    for (uint32_t pgen_ndx = 0; pgen_ndx < ktl::size(PRIORITY_GENERATORS); ++pgen_ndx) {
      PRINT_LOOP_ITER(pgen_ndx);

      // At the end of the tests, success or failure, be sure to clean up.
      auto cleanup = fit::defer([&]() {
        TestThread::ClearShutdownBarrier();
        blocking_queue.ReleaseAllThreads();
        blocking_thread.Reset();
        for (auto& w : *waiters) {
          w.thread.Reset();
        }
      });

      // Make sure that our barriers have been reset.
      TestThread::ResetShutdownBarrier();

      // Generate the priority map for this pass.
      int prio_map[WAITER_CNT];
      CreateDistribution(prio_map, PRIORITY_GENERATORS[pgen_ndx]);

      // Create all of the threads.
      ASSERT_TRUE(blocking_thread.Create(bt_prio));
      for (uint32_t waiter_ndx = 0; waiter_ndx < waiters->size(); ++waiter_ndx) {
        PRINT_LOOP_ITER(waiter_ndx);

        auto& w = (*waiters)[waiter_ndx];
        w.prio = prio_map[waiter_ndx];
        ASSERT_TRUE(w.thread.Create(w.prio));

        print_waiter_ndx.cancel();
      }

      // Define a small lambda we will use to validate the expected priorities of
      // each of our threads.
      TestThread* current_owner = &blocking_thread;
      auto ValidatePriorities = [&]() -> bool {
        BEGIN_TEST;

        // All threads in the test who are not the current owner should have
        // their effective priority be equal to their base priority
        if (&blocking_thread != current_owner) {
          ASSERT_EQ(bt_prio, blocking_thread.effective_priority());
        }

        for (uint32_t waiter_ndx = 0; waiter_ndx < waiters->size(); ++waiter_ndx) {
          PRINT_LOOP_ITER(waiter_ndx);

          auto& w = (*waiters)[waiter_ndx];
          if (&w.thread != current_owner) {
            ASSERT_EQ(prio_map[waiter_ndx], w.thread.effective_priority());
          }

          print_waiter_ndx.cancel();
        }

        // The current owner (if any) should have the max priority across all of
        // the waiters, and its own base priority.
        ASSERT_NONNULL(current_owner);
        int expected_prio = current_owner->base_priority();
        for (const auto& w : *waiters) {
          if (w.is_waiting && (expected_prio < w.prio)) {
            expected_prio = w.prio;
          }
        }
        ASSERT_EQ(expected_prio, current_owner->effective_priority());

        END_TEST;
      };

      // Start the blocking thread.
      ASSERT_TRUE(blocking_thread.DoStall());
      ASSERT_TRUE(ValidatePriorities());

      // Start each of the threads and have them block on the blocking_queue,
      // declaring blocking_thread to be the owner as they go.  Verify that the
      // blocking thread has the priority of the highest priority thread who is
      // currently waiting.
      for (uint32_t waiter_ndx = 0; waiter_ndx < waiters->size(); ++waiter_ndx) {
        PRINT_LOOP_ITER(waiter_ndx);

        auto& w = (*waiters)[waiter_ndx];
        ASSERT_TRUE(w.thread.BlockOnOwnedQueue(&blocking_queue, current_owner));
        w.is_waiting = true;
        ASSERT_TRUE(ValidatePriorities());

        print_waiter_ndx.cancel();
      }

      // Now wake the threads, one at a time, assigning ownership to the thread
      // which was woken each time.  Note that we should not be assuming which
      // thread is going to be woken.  We will need to request that a thread be
      // woken, then figure out after the fact which one was.
      for (uint32_t tndx = 0; tndx < waiters->size(); ++tndx) {
        PRINT_LOOP_ITER(tndx);

        blocking_queue.ReleaseOneThread();

        TestThread* new_owner = nullptr;
        zx_time_t deadline = current_time() + ZX_SEC(10);
        while (current_time() < deadline) {
          for (auto& w : *waiters) {
            // If the waiter's is_waiting flag is set, but the thread has
            // reached the WAITING_FOR_SHUTDOWN state, then we know that
            // this was a thread which was just woken.
            if (w.is_waiting && (w.thread.state() == TestThread::State::WAITING_FOR_SHUTDOWN)) {
              new_owner = &w.thread;
              w.is_waiting = false;
              break;
            }
          }

          if (new_owner != nullptr) {
            break;
          }

          Thread::Current::SleepRelative(ZX_USEC(100));
        }

        // Sanity checks.  Make sure that the new owner exists, and is not the
        // same as the old owner.  Also make sure that none of the other threads
        // have been released but have not been recognized yet.
        ASSERT_NONNULL(new_owner);
        ASSERT_NE(new_owner, current_owner);
        for (auto& w : *waiters) {
          if (w.is_waiting) {
            ASSERT_EQ(TestThread::State::STARTED, w.thread.state());
          } else {
            ASSERT_EQ(TestThread::State::WAITING_FOR_SHUTDOWN, w.thread.state());
          }
        }
        current_owner = new_owner;

        // Validate our priorities.
        ASSERT_TRUE(ValidatePriorities());

        print_tndx.cancel();
      }

      print_pgen_ndx.cancel();
    }
    print_bt_prio.cancel();
  }

  END_TEST;
}

template <uint32_t QUEUE_CNT>
bool pi_test_multi_owned_queues() {
  static_assert(QUEUE_CNT >= 2, "Must have at least 2 owned queues in the multi-waiter test");
  static_assert(QUEUE_CNT < TEST_PRIORTY_COUNT,
                "Multi waiter test must have fewer owned queues than priority levels");
  BEGIN_TEST;
  fbl::AllocChecker ac;
  AutoPrioBooster pboost;

  TestThread blocking_thread;
  struct Waiter {
    TestThread thread;
    LockedOwnedWaitQueue queue;
    bool is_waiting = false;
    int prio = 0;
  };
  auto queues = ktl::make_unique<ktl::array<Waiter, QUEUE_CNT>>(&ac);
  ASSERT_TRUE(ac.check());

  const int BLOCKING_THREAD_PRIO[] = {TEST_LOWEST_PRIORITY, TEST_DEFAULT_PRIORITY,
                                      TEST_HIGHEST_PRIORITY - 1};
  const DistroSpec PRIORITY_GENERATORS[] = {
      {DistroSpec::Type::ASCENDING, TEST_LOWEST_PRIORITY},
      {DistroSpec::Type::DESCENDING, TEST_LOWEST_PRIORITY},
      {DistroSpec::Type::SAME, TEST_DEFAULT_PRIORITY},
      {DistroSpec::Type::RANDOM, TEST_LOWEST_PRIORITY, 0xef900a44da89a82d},
      {DistroSpec::Type::RANDOM, TEST_LOWEST_PRIORITY, 0xb89e3b7442b95a1c},
      {DistroSpec::Type::SHUFFLE, TEST_LOWEST_PRIORITY, 0xa23574c4fb9b0a10},
      {DistroSpec::Type::SHUFFLE, TEST_LOWEST_PRIORITY, 0x06ec82d4ade8efba},
  };

  for (auto bt_prio : BLOCKING_THREAD_PRIO) {
    PRINT_LOOP_ITER(bt_prio);

    for (uint32_t pgen_ndx = 0; pgen_ndx < ktl::size(PRIORITY_GENERATORS); ++pgen_ndx) {
      PRINT_LOOP_ITER(pgen_ndx);

      // At the end of the tests, success or failure, be sure to clean up.
      auto cleanup = fit::defer([&]() {
        TestThread::ClearShutdownBarrier();
        blocking_thread.Reset();
        for (auto& q : *queues) {
          q.queue.ReleaseAllThreads();
        }
        for (auto& q : *queues) {
          q.thread.Reset();
        }
      });

      // Make sure that our barriers have been reset.
      TestThread::ResetShutdownBarrier();

      // Generate the priority map for this pass.
      int prio_map[QUEUE_CNT];
      CreateDistribution(prio_map, PRIORITY_GENERATORS[pgen_ndx]);

      // Create all of the threads.
      ASSERT_TRUE(blocking_thread.Create(bt_prio));
      for (uint32_t queue_ndx = 0; queue_ndx < queues->size(); ++queue_ndx) {
        PRINT_LOOP_ITER(queue_ndx);

        auto& q = (*queues)[queue_ndx];
        q.prio = prio_map[queue_ndx];
        ASSERT_TRUE(q.thread.Create(q.prio));

        print_queue_ndx.cancel();
      }

      // Define a small lambda we will use to validate the expected priorities of
      // each of our threads.
      auto ValidatePriorities = [&]() -> bool {
        BEGIN_TEST;

        // Each of the queue threads should simply have their base
        // priority.  Verify this while we compute the maximum priority
        // across all of the threads who are still applying pressure to
        // the blocking thread.
        int max_pressure = -1;
        for (const auto& q : *queues) {
          ASSERT_EQ(q.prio, q.thread.effective_priority());
          if (q.is_waiting) {
            max_pressure = ktl::max(max_pressure, q.prio);
          }
        }

        for (uint32_t queue_ndx = 0; queue_ndx < queues->size(); ++queue_ndx) {
          PRINT_LOOP_ITER(queue_ndx);
          const auto& q = (*queues)[queue_ndx];

          ASSERT_EQ(q.prio, q.thread.effective_priority());
          if (q.is_waiting) {
            max_pressure = ktl::max(max_pressure, q.prio);
          }

          print_queue_ndx.cancel();
        }

        // Now that we know the pressure which is being applied to the
        // blocking thread, verify its effective priority.
        int expected_prio = ktl::max(max_pressure, bt_prio);
        ASSERT_EQ(expected_prio, blocking_thread.effective_priority());

        END_TEST;
      };

      // Start the blocking thread.
      ASSERT_TRUE(blocking_thread.DoStall());
      ASSERT_TRUE(ValidatePriorities());

      // Start each of the threads and have them block on their associated
      // queue, declaring blocking_thread to be the owner of their queue
      // as they go.  Validate priorities at each step.
      for (uint32_t queue_ndx = 0; queue_ndx < queues->size(); ++queue_ndx) {
        PRINT_LOOP_ITER(queue_ndx);

        auto& q = (*queues)[queue_ndx];
        ASSERT_TRUE(q.thread.BlockOnOwnedQueue(&q.queue, &blocking_thread));
        q.is_waiting = true;
        ASSERT_TRUE(ValidatePriorities());

        print_queue_ndx.cancel();
      }

      // Now wake the threads, one at a time, verifying priorities as we
      // go.
      for (uint32_t queue_ndx = 0; queue_ndx < queues->size(); ++queue_ndx) {
        PRINT_LOOP_ITER(queue_ndx);

        auto& q = (*queues)[queue_ndx];
        q.queue.ReleaseOneThread();
        q.is_waiting = false;
        ASSERT_TRUE(ValidatePriorities());

        print_queue_ndx.cancel();
      }

      print_pgen_ndx.cancel();
    }
    print_bt_prio.cancel();
  }

  END_TEST;
}

template <uint32_t CYCLE_LEN>
bool pi_test_cycle() {
  static_assert(CYCLE_LEN >= 2, "Must have at least 2 nodes to form a PI cycle");
  static_assert(CYCLE_LEN < TEST_PRIORTY_COUNT,
                "Cannot create a cycle which would result in a thread being created at "
                "TEST_HIGHEST_PRIORITY");
  BEGIN_TEST;
  fbl::AllocChecker ac;
  AutoPrioBooster pboost;

  // Deliberately create a cycle and make sure that we don't hang or otherwise
  // exhibit bad behavior.
  struct Link {
    TestThread thread;
    LockedOwnedWaitQueue link;
  };
  auto nodes = ktl::make_unique<ktl::array<Link, CYCLE_LEN>>(&ac);
  ASSERT_TRUE(ac.check());

  // At the end of the tests, success or failure, be sure to clean up.
  auto cleanup = fit::defer([&]() {
    TestThread::ClearShutdownBarrier();
    for (auto& n : *nodes) {
      n.link.ReleaseAllThreads();
    }
    for (auto& n : *nodes) {
      n.thread.Reset();
    }
  });

  // Create the priorities we will assign to each thread.
  int prio_map[CYCLE_LEN];
  CreateDistribution(prio_map, {DistroSpec::Type::ASCENDING, TEST_LOWEST_PRIORITY});

  // Create each thread
  for (uint32_t tndx = 0; tndx < nodes->size(); ++tndx) {
    PRINT_LOOP_ITER(tndx);
    ASSERT_TRUE((*nodes)[tndx].thread.Create(prio_map[tndx]));
    print_tndx.cancel();
  }

  // Let each thread run, blocking it on its own link and declaring the next
  // thread in the list to be the owner of the link.  When we hit the last
  // thread, we form a cycle.  Our threads are in ascending priority order, so
  // we should not see any PI ripple until the final link has been made.  At
  // that point, all of the threads in the test should have the priority of
  // the final thread.
  for (uint32_t tndx = 0; tndx < nodes->size(); ++tndx) {
    PRINT_LOOP_ITER(tndx);

    auto owner_thread = &(*nodes)[(tndx + 1) % nodes->size()].thread;
    auto link_ptr = &(*nodes)[tndx].link;
    ASSERT_TRUE((*nodes)[tndx].thread.BlockOnOwnedQueue(link_ptr, owner_thread));

    for (uint32_t validation_ndx = 0; validation_ndx <= tndx; ++validation_ndx) {
      PRINT_LOOP_ITER(validation_ndx);

      int expected_prio = prio_map[(tndx == (nodes->size() - 1)) ? tndx : validation_ndx];
      ASSERT_EQ(expected_prio, (*nodes)[validation_ndx].thread.effective_priority());

      print_validation_ndx.cancel();
    }

    print_tndx.cancel();
  }

  END_TEST;
}

// Exercise the specific failure tracked down during the investigation of fxbug.dev/33934
//
// There are a few different ways that this situation can be forced to happen.
// See the bug writeup for details.
bool pi_test_zx4153() {
  BEGIN_TEST;
  AutoPrioBooster pboost;

  // Repro of this involves 2 threads and 2 wait queues involved in a PI
  // cycle.  The simplest repro is as follows.
  //
  // Let T1.prio == 16
  // Let T2.prio == 17
  //
  // 1) Block T1 on Q2 and declare T2 to be the owner of Q2
  // 2) Block T2 on Q1 and declare T1 to be the owner of Q1.  T1 and T2 now
  //    form a cycle.  The inherited priority of the cycle is now 17.
  // 3) Raise T1's priority to 20.  The cycle priority is now up to 20.
  // 4) Lower T1's priority back down to 16.  The cycle priority remains at
  //    20.  It cannot relax until the cycle is broken.
  // 5) Break the cycle by declaring Q1 to have no owner.  Do not wake T1.
  //
  // If the bookkeeping error found in fxbug.dev/33934 was still around, the effect
  // would be...
  //
  // 1) T1 no longer feels pressure from Q1.  T1's effective priority drops
  //    from 20 to 16 (its base priority)
  // 2) T1 is the only waiter on Q2.  Q2's pressure drops from 20 -> 16
  // 3) The pressure applied to T2 drops from 20 -> 16.  T2's effective
  //    priority is now 17 (its base priority).
  // 4) T2 is the only waiter on Q1.  Q1's pressure drops from 20 -> 17
  // 5) Q1's owner is still mistakenly set to T1.  T1 receives Q1's pressure,
  //    and its inherited priority goes from -1 -> 17.
  // 6) Q1 now owns no queues, but has inherited priority.  This should be
  //    impossible, and triggers the assert.
  //

  TestThread T1, T2;
  LockedOwnedWaitQueue Q1, Q2;

  // At the end of the tests, success or failure, be sure to clean up.
  auto cleanup = fit::defer([&]() {
    TestThread::ClearShutdownBarrier();
    Q1.ReleaseAllThreads();
    Q2.ReleaseAllThreads();
    T1.Reset();
    T2.Reset();
  });

  constexpr int kT1InitialPrio = 16;
  constexpr int kT2InitialPrio = 17;
  constexpr int kT1BoostPrio = 20;

  // Create the threads.
  ASSERT_TRUE(T1.Create(kT1InitialPrio));
  ASSERT_TRUE(T2.Create(kT2InitialPrio));

  ASSERT_EQ(T1.base_priority(), kT1InitialPrio);
  ASSERT_EQ(T1.inherited_priority(), -1);
  ASSERT_EQ(T1.effective_priority(), kT1InitialPrio);

  ASSERT_EQ(T2.base_priority(), kT2InitialPrio);
  ASSERT_EQ(T2.inherited_priority(), -1);
  ASSERT_EQ(T2.effective_priority(), kT2InitialPrio);

  // Form the cycle, verify the priorities
  ASSERT_TRUE(T1.BlockOnOwnedQueue(&Q2, &T2));
  ASSERT_TRUE(T2.BlockOnOwnedQueue(&Q1, &T1));

  ASSERT_EQ(T1.base_priority(), kT1InitialPrio);
  ASSERT_EQ(T1.inherited_priority(), kT2InitialPrio);
  ASSERT_EQ(T1.effective_priority(), kT2InitialPrio);

  ASSERT_EQ(T2.base_priority(), kT2InitialPrio);
  ASSERT_EQ(T2.inherited_priority(), kT2InitialPrio);
  ASSERT_EQ(T2.effective_priority(), kT2InitialPrio);

  // Boost T1's priority.
  ASSERT_TRUE(T1.SetBasePriority(kT1BoostPrio));

  ASSERT_EQ(T1.base_priority(), kT1BoostPrio);
  ASSERT_EQ(T1.inherited_priority(), kT1BoostPrio);
  ASSERT_EQ(T1.effective_priority(), kT1BoostPrio);

  ASSERT_EQ(T2.base_priority(), kT2InitialPrio);
  ASSERT_EQ(T2.inherited_priority(), kT1BoostPrio);
  ASSERT_EQ(T2.effective_priority(), kT1BoostPrio);

  // Relax T1's priority.  The cycle's priority cannot relax yet.
  ASSERT_TRUE(T1.SetBasePriority(kT1InitialPrio));

  ASSERT_EQ(T1.base_priority(), kT1InitialPrio);
  ASSERT_EQ(T1.inherited_priority(), kT1BoostPrio);
  ASSERT_EQ(T1.effective_priority(), kT1BoostPrio);

  ASSERT_EQ(T2.base_priority(), kT2InitialPrio);
  ASSERT_EQ(T2.inherited_priority(), kT1BoostPrio);
  ASSERT_EQ(T2.effective_priority(), kT1BoostPrio);

  // Release ownership of Q1, breaking the cycle.  T2 should feel the pressure
  // from T1, but T1 should not be inheriting any priority anymore.
  Q1.AssignOwner(nullptr);

  ASSERT_EQ(T1.base_priority(), kT1InitialPrio);
  ASSERT_EQ(T1.inherited_priority(), -1);
  ASSERT_EQ(T1.effective_priority(), kT1InitialPrio);

  ASSERT_EQ(T2.base_priority(), kT2InitialPrio);
  ASSERT_EQ(T2.inherited_priority(), kT1InitialPrio);
  ASSERT_EQ(T2.effective_priority(), kT2InitialPrio);

  // Success!  Let the cleanup AutoCall do its job.

  END_TEST;
}

}  // namespace

UNITTEST_START_TESTCASE(pi_tests)
UNITTEST("basic", pi_test_basic)
UNITTEST("changing priority", pi_test_changing_priority)
UNITTEST("long chains", pi_test_chain<29>)
UNITTEST("multiple waiters", pi_test_multi_waiter<29>)
UNITTEST("multiple owned queues", pi_test_multi_owned_queues<29>)
UNITTEST("cycles", pi_test_cycle<29>)
UNITTEST("fxbug.dev/33934", pi_test_zx4153)
UNITTEST_END_TESTCASE(pi_tests, "pi", "Priority inheritance tests for OwnedWaitQueues")
