// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/platform_thread.h"

#include <stddef.h>

#include "base/compiler_specific.h"
#include "base/process/process.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread.h"
#include "base/threading/threading_features.h"
#include "build/blink_buildflags.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_POSIX)
#include "base/threading/platform_thread_internal_posix.h"
#elif BUILDFLAG(IS_WIN)
#include <windows.h>
#include "base/threading/platform_thread_win.h"
#endif

#if BUILDFLAG(IS_APPLE)
#include <mach/mach.h>
#include <mach/mach_time.h>
#include <mach/thread_policy.h>
#include "base/mac/mac_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/time/time.h"
#endif

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include <pthread.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#endif

namespace base {

// Trivial tests that thread runs and doesn't crash on create, join, or detach -

namespace {

class TrivialThread : public PlatformThread::Delegate {
 public:
  TrivialThread() : run_event_(WaitableEvent::ResetPolicy::MANUAL,
                               WaitableEvent::InitialState::NOT_SIGNALED) {}

  TrivialThread(const TrivialThread&) = delete;
  TrivialThread& operator=(const TrivialThread&) = delete;

  void ThreadMain() override { run_event_.Signal(); }

  WaitableEvent& run_event() { return run_event_; }

 private:
  WaitableEvent run_event_;
};

}  // namespace

TEST(PlatformThreadTest, TrivialJoin) {
  TrivialThread thread;
  PlatformThreadHandle handle;

  ASSERT_FALSE(thread.run_event().IsSignaled());
  ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
  PlatformThread::Join(handle);
  ASSERT_TRUE(thread.run_event().IsSignaled());
}

TEST(PlatformThreadTest, TrivialJoinTimesTen) {
  TrivialThread thread[10];
  PlatformThreadHandle handle[std::size(thread)];

  for (auto& n : thread)
    ASSERT_FALSE(n.run_event().IsSignaled());
  for (size_t n = 0; n < std::size(thread); n++)
    ASSERT_TRUE(PlatformThread::Create(0, &thread[n], &handle[n]));
  for (auto n : handle)
    PlatformThread::Join(n);
  for (auto& n : thread)
    ASSERT_TRUE(n.run_event().IsSignaled());
}

// The following detach tests are by nature racy. The run_event approximates the
// end and termination of the thread, but threads could persist shortly after
// the test completes.
TEST(PlatformThreadTest, TrivialDetach) {
  TrivialThread thread;
  PlatformThreadHandle handle;

  ASSERT_FALSE(thread.run_event().IsSignaled());
  ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
  PlatformThread::Detach(handle);
  thread.run_event().Wait();
}

TEST(PlatformThreadTest, TrivialDetachTimesTen) {
  TrivialThread thread[10];
  PlatformThreadHandle handle[std::size(thread)];

  for (auto& n : thread)
    ASSERT_FALSE(n.run_event().IsSignaled());
  for (size_t n = 0; n < std::size(thread); n++) {
    ASSERT_TRUE(PlatformThread::Create(0, &thread[n], &handle[n]));
    PlatformThread::Detach(handle[n]);
  }
  for (auto& n : thread)
    n.run_event().Wait();
}

// Tests of basic thread functions ---------------------------------------------

namespace {

class FunctionTestThread : public PlatformThread::Delegate {
 public:
  FunctionTestThread()
      : thread_id_(kInvalidThreadId),
        termination_ready_(WaitableEvent::ResetPolicy::MANUAL,
                           WaitableEvent::InitialState::NOT_SIGNALED),
        terminate_thread_(WaitableEvent::ResetPolicy::MANUAL,
                          WaitableEvent::InitialState::NOT_SIGNALED),
        done_(false) {}

  FunctionTestThread(const FunctionTestThread&) = delete;
  FunctionTestThread& operator=(const FunctionTestThread&) = delete;

  ~FunctionTestThread() override {
    EXPECT_TRUE(terminate_thread_.IsSignaled())
        << "Need to mark thread for termination and join the underlying thread "
        << "before destroying a FunctionTestThread as it owns the "
        << "WaitableEvent blocking the underlying thread's main.";
  }

  // Grabs |thread_id_|, runs an optional test on that thread, signals
  // |termination_ready_|, and then waits for |terminate_thread_| to be
  // signaled before exiting.
  void ThreadMain() override {
    thread_id_ = PlatformThread::CurrentId();
    EXPECT_NE(thread_id_, kInvalidThreadId);

    // Make sure that the thread ID is the same across calls.
    EXPECT_EQ(thread_id_, PlatformThread::CurrentId());

    // Run extra tests.
    RunTest();

    termination_ready_.Signal();
    terminate_thread_.Wait();

    done_ = true;
  }

  PlatformThreadId thread_id() const {
    EXPECT_TRUE(termination_ready_.IsSignaled()) << "Thread ID still unknown";
    return thread_id_;
  }

  bool IsRunning() const {
    return termination_ready_.IsSignaled() && !done_;
  }

  // Blocks until this thread is started and ready to be terminated.
  void WaitForTerminationReady() { termination_ready_.Wait(); }

  // Marks this thread for termination (callers must then join this thread to be
  // guaranteed of termination).
  void MarkForTermination() { terminate_thread_.Signal(); }

 private:
  // Runs an optional test on the newly created thread.
  virtual void RunTest() {}

  PlatformThreadId thread_id_;

  mutable WaitableEvent termination_ready_;
  WaitableEvent terminate_thread_;
  bool done_;
};

}  // namespace

TEST(PlatformThreadTest, Function) {
  PlatformThreadId main_thread_id = PlatformThread::CurrentId();

  FunctionTestThread thread;
  PlatformThreadHandle handle;

  ASSERT_FALSE(thread.IsRunning());
  ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
  thread.WaitForTerminationReady();
  ASSERT_TRUE(thread.IsRunning());
  EXPECT_NE(thread.thread_id(), main_thread_id);

  thread.MarkForTermination();
  PlatformThread::Join(handle);
  ASSERT_FALSE(thread.IsRunning());

  // Make sure that the thread ID is the same across calls.
  EXPECT_EQ(main_thread_id, PlatformThread::CurrentId());
}

TEST(PlatformThreadTest, FunctionTimesTen) {
  PlatformThreadId main_thread_id = PlatformThread::CurrentId();

  FunctionTestThread thread[10];
  PlatformThreadHandle handle[std::size(thread)];

  for (const auto& n : thread)
    ASSERT_FALSE(n.IsRunning());

  for (size_t n = 0; n < std::size(thread); n++)
    ASSERT_TRUE(PlatformThread::Create(0, &thread[n], &handle[n]));
  for (auto& n : thread)
    n.WaitForTerminationReady();

  for (size_t n = 0; n < std::size(thread); n++) {
    ASSERT_TRUE(thread[n].IsRunning());
    EXPECT_NE(thread[n].thread_id(), main_thread_id);

    // Make sure no two threads get the same ID.
    for (size_t i = 0; i < n; ++i) {
      EXPECT_NE(thread[i].thread_id(), thread[n].thread_id());
    }
  }

  for (auto& n : thread)
    n.MarkForTermination();
  for (auto n : handle)
    PlatformThread::Join(n);
  for (const auto& n : thread)
    ASSERT_FALSE(n.IsRunning());

  // Make sure that the thread ID is the same across calls.
  EXPECT_EQ(main_thread_id, PlatformThread::CurrentId());
}

namespace {

constexpr ThreadType kAllThreadTypes[] = {
    ThreadType::kRealtimeAudio,     ThreadType::kDisplayCritical,
    ThreadType::kCompositing,       ThreadType::kDefault,
    ThreadType::kResourceEfficient, ThreadType::kUtility,
    ThreadType::kBackground};

class ThreadTypeTestThread : public FunctionTestThread {
 public:
  explicit ThreadTypeTestThread(ThreadType from, ThreadType to)
      : from_(from), to_(to) {}

  ThreadTypeTestThread(const ThreadTypeTestThread&) = delete;
  ThreadTypeTestThread& operator=(const ThreadTypeTestThread&) = delete;

  ~ThreadTypeTestThread() override = default;

 private:
  void RunTest() override {
    EXPECT_EQ(PlatformThread::GetCurrentThreadType(), ThreadType::kDefault);
    PlatformThread::SetCurrentThreadType(from_);
    EXPECT_EQ(PlatformThread::GetCurrentThreadType(), from_);
    PlatformThread::SetCurrentThreadType(to_);
    EXPECT_EQ(PlatformThread::GetCurrentThreadType(), to_);
  }

  const ThreadType from_;
  const ThreadType to_;
};

class ThreadPriorityTestThread : public FunctionTestThread {
 public:
  ThreadPriorityTestThread(ThreadType thread_type,
                           ThreadPriorityForTest priority)
      : thread_type_(thread_type), priority(priority) {}

 private:
  void RunTest() override {
    testing::Message message;
    message << "thread_type: " << static_cast<int>(thread_type_);
    SCOPED_TRACE(message);

    EXPECT_EQ(PlatformThread::GetCurrentThreadType(), ThreadType::kDefault);
    PlatformThread::SetCurrentThreadType(thread_type_);
    EXPECT_EQ(PlatformThread::GetCurrentThreadType(), thread_type_);
    if (PlatformThread::CanChangeThreadType(ThreadType::kDefault,
                                            thread_type_)) {
      EXPECT_EQ(PlatformThread::GetCurrentThreadPriorityForTest(), priority);
    }
  }

  const ThreadType thread_type_;
  const ThreadPriorityForTest priority;
};

void TestSetCurrentThreadType() {
  for (auto from : kAllThreadTypes) {
    if (!PlatformThread::CanChangeThreadType(ThreadType::kDefault, from)) {
      continue;
    }
    for (auto to : kAllThreadTypes) {
      ThreadTypeTestThread thread(from, to);
      PlatformThreadHandle handle;

      ASSERT_FALSE(thread.IsRunning());
      ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
      thread.WaitForTerminationReady();
      ASSERT_TRUE(thread.IsRunning());

      thread.MarkForTermination();
      PlatformThread::Join(handle);
      ASSERT_FALSE(thread.IsRunning());
    }
  }
}

void TestPriorityResultingFromThreadType(ThreadType thread_type,
                                         ThreadPriorityForTest priority) {
  ThreadPriorityTestThread thread(thread_type, priority);
  PlatformThreadHandle handle;

  ASSERT_FALSE(thread.IsRunning());
  ASSERT_TRUE(PlatformThread::Create(0, &thread, &handle));
  thread.WaitForTerminationReady();
  ASSERT_TRUE(thread.IsRunning());

  thread.MarkForTermination();
  PlatformThread::Join(handle);
  ASSERT_FALSE(thread.IsRunning());
}

ThreadPriorityForTest GetCurrentThreadPriorityIfStartWithThreadType(
    ThreadType thread_type,
    MessagePumpType message_pump_type) {
  Thread::Options options;
  options.thread_type = thread_type;
  options.message_pump_type = message_pump_type;

  Thread thread("GetCurrentThreadPriorityIfStartWithThreadType");
  thread.StartWithOptions(std::move(options));
  thread.WaitUntilThreadStarted();

  ThreadPriorityForTest priority;
  thread.task_runner()->PostTask(
      FROM_HERE, BindOnce(
                     [](ThreadPriorityForTest* priority) {
                       *priority =
                           PlatformThread::GetCurrentThreadPriorityForTest();
                     },
                     &priority));
  thread.Stop();

  return priority;
}

ThreadPriorityForTest GetCurrentThreadPriorityIfSetThreadTypeLater(
    ThreadType thread_type,
    MessagePumpType message_pump_type) {
  Thread::Options options;
  options.message_pump_type = message_pump_type;

  Thread thread("GetCurrentThreadPriorityIfSetThreadTypeLater");
  thread.StartWithOptions(std::move(options));
  thread.WaitUntilThreadStarted();

  ThreadPriorityForTest priority;
  thread.task_runner()->PostTask(
      FROM_HERE,
      BindOnce(
          [](ThreadType thread_type, ThreadPriorityForTest* priority) {
            PlatformThread::SetCurrentThreadType(thread_type);
            *priority = PlatformThread::GetCurrentThreadPriorityForTest();
          },
          thread_type, &priority));
  thread.Stop();

  return priority;
}

void TestPriorityResultingFromThreadType(ThreadType thread_type,
                                         MessagePumpType message_pump_type,
                                         ThreadPriorityForTest priority) {
  testing::Message message;
  message << "thread_type: " << static_cast<int>(thread_type)
          << ", message_pump_type: " << static_cast<int>(message_pump_type);
  SCOPED_TRACE(message);

  if (PlatformThread::CanChangeThreadType(ThreadType::kDefault, thread_type)) {
    EXPECT_EQ(GetCurrentThreadPriorityIfStartWithThreadType(thread_type,
                                                            message_pump_type),
              priority);
    EXPECT_EQ(GetCurrentThreadPriorityIfSetThreadTypeLater(thread_type,
                                                           message_pump_type),
              priority);
  }
}

}  // namespace

// Test changing a created thread's type.
TEST(PlatformThreadTest, SetCurrentThreadType) {
  TestSetCurrentThreadType();
}

#if BUILDFLAG(IS_WIN)
// Test changing a created thread's priority in an IDLE_PRIORITY_CLASS process
// (regression test for https://crbug.com/901483).
TEST(PlatformThreadTest,
     SetCurrentThreadTypeWithThreadModeBackgroundIdleProcess) {
  ::SetPriorityClass(Process::Current().Handle(), IDLE_PRIORITY_CLASS);
  TestSetCurrentThreadType();
  ::SetPriorityClass(Process::Current().Handle(), NORMAL_PRIORITY_CLASS);
}
#endif  // BUILDFLAG(IS_WIN)

// Ideally PlatformThread::CanChangeThreadType() would be true on all
// platforms for all priorities. This not being the case. This test documents
// and hardcodes what we know. Please inform scheduler-dev@chromium.org if this
// proprerty changes for a given platform.
TEST(PlatformThreadTest, CanChangeThreadType) {
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  // On Ubuntu, RLIMIT_NICE and RLIMIT_RTPRIO are 0 by default, so we won't be
  // able to increase priority to any level unless we are root (euid == 0).
  bool kCanIncreasePriority = false;
  if (geteuid() == 0) {
    kCanIncreasePriority = true;
  }

#else
  constexpr bool kCanIncreasePriority = true;
#endif

  for (auto type : kAllThreadTypes) {
    EXPECT_TRUE(PlatformThread::CanChangeThreadType(type, type));
  }
#if BUILDFLAG(IS_FUCHSIA)
  EXPECT_FALSE(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                   ThreadType::kUtility));
  EXPECT_FALSE(PlatformThread::CanChangeThreadType(
      ThreadType::kBackground, ThreadType::kResourceEfficient));
  EXPECT_FALSE(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                   ThreadType::kDefault));
  EXPECT_FALSE(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                   ThreadType::kCompositing));
  EXPECT_FALSE(PlatformThread::CanChangeThreadType(ThreadType::kDefault,
                                                   ThreadType::kBackground));
  EXPECT_FALSE(PlatformThread::CanChangeThreadType(ThreadType::kCompositing,
                                                   ThreadType::kBackground));
#else
  EXPECT_EQ(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                ThreadType::kUtility),
            kCanIncreasePriority);
  EXPECT_EQ(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                ThreadType::kResourceEfficient),
            kCanIncreasePriority);
  EXPECT_EQ(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                ThreadType::kDefault),
            kCanIncreasePriority);
  EXPECT_EQ(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                ThreadType::kCompositing),
            kCanIncreasePriority);
  EXPECT_TRUE(PlatformThread::CanChangeThreadType(ThreadType::kDefault,
                                                  ThreadType::kBackground));
  EXPECT_TRUE(PlatformThread::CanChangeThreadType(ThreadType::kCompositing,
                                                  ThreadType::kBackground));
#endif
  EXPECT_EQ(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                ThreadType::kDisplayCritical),
            kCanIncreasePriority);
  EXPECT_EQ(PlatformThread::CanChangeThreadType(ThreadType::kBackground,
                                                ThreadType::kRealtimeAudio),
            kCanIncreasePriority);
#if BUILDFLAG(IS_FUCHSIA)
  EXPECT_FALSE(PlatformThread::CanChangeThreadType(ThreadType::kDisplayCritical,
                                                   ThreadType::kBackground));
  EXPECT_FALSE(PlatformThread::CanChangeThreadType(ThreadType::kRealtimeAudio,
                                                   ThreadType::kBackground));
#else
  EXPECT_TRUE(PlatformThread::CanChangeThreadType(ThreadType::kDisplayCritical,
                                                  ThreadType::kBackground));
  EXPECT_TRUE(PlatformThread::CanChangeThreadType(ThreadType::kRealtimeAudio,
                                                  ThreadType::kBackground));
#endif
}

TEST(PlatformThreadTest, SetCurrentThreadTypeTest) {
  TestPriorityResultingFromThreadType(ThreadType::kBackground,
                                      ThreadPriorityForTest::kBackground);
  TestPriorityResultingFromThreadType(ThreadType::kUtility,
                                      ThreadPriorityForTest::kUtility);

#if BUILDFLAG(IS_APPLE)
  TestPriorityResultingFromThreadType(ThreadType::kResourceEfficient,
                                      ThreadPriorityForTest::kUtility);
#elif BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
  TestPriorityResultingFromThreadType(
      ThreadType::kResourceEfficient,
      ThreadPriorityForTest::kResourceEfficient);
#else
  TestPriorityResultingFromThreadType(ThreadType::kResourceEfficient,
                                      ThreadPriorityForTest::kNormal);
#endif  // BUILDFLAG(IS_APPLE)

  TestPriorityResultingFromThreadType(ThreadType::kDefault,
                                      ThreadPriorityForTest::kNormal);

#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
  TestPriorityResultingFromThreadType(ThreadType::kCompositing,
                                      ThreadPriorityForTest::kDisplay);
  TestPriorityResultingFromThreadType(ThreadType::kCompositing,
                                      MessagePumpType::UI,
                                      ThreadPriorityForTest::kDisplay);
  TestPriorityResultingFromThreadType(ThreadType::kCompositing,
                                      MessagePumpType::IO,
                                      ThreadPriorityForTest::kDisplay);
#else  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_FUCHSIA)
  TestPriorityResultingFromThreadType(ThreadType::kCompositing,
                                      ThreadPriorityForTest::kNormal);
  TestPriorityResultingFromThreadType(ThreadType::kCompositing,
                                      MessagePumpType::UI,
                                      ThreadPriorityForTest::kNormal);
  TestPriorityResultingFromThreadType(ThreadType::kCompositing,
                                      MessagePumpType::IO,
                                      ThreadPriorityForTest::kNormal);
#endif
  TestPriorityResultingFromThreadType(ThreadType::kDisplayCritical,
                                      ThreadPriorityForTest::kDisplay);
  TestPriorityResultingFromThreadType(ThreadType::kRealtimeAudio,
                                      ThreadPriorityForTest::kRealtimeAudio);
}

TEST(PlatformThreadTest, SetHugeThreadName) {
  // Construct an excessively long thread name.
  std::string long_name(1024, 'a');

  // SetName has no return code, so just verify that implementations
  // don't [D]CHECK().
  PlatformThread::SetName(long_name);
}

TEST(PlatformThreadTest, GetDefaultThreadStackSize) {
  size_t stack_size = PlatformThread::GetDefaultThreadStackSize();
#if BUILDFLAG(IS_IOS) && BUILDFLAG(USE_BLINK)
  EXPECT_EQ(1024u * 1024u, stack_size);
#elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_IOS) || BUILDFLAG(IS_FUCHSIA) ||      \
    ((BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(__GLIBC__) && \
     !defined(THREAD_SANITIZER)) ||                                           \
    (BUILDFLAG(IS_ANDROID) && !defined(ADDRESS_SANITIZER))
  EXPECT_EQ(0u, stack_size);
#else
  EXPECT_GT(stack_size, 0u);
  EXPECT_LT(stack_size, 20u * (1 << 20));
#endif
}

#if BUILDFLAG(IS_APPLE)

namespace {

class RealtimeTestThread : public FunctionTestThread {
 public:
  explicit RealtimeTestThread(TimeDelta realtime_period)
      : realtime_period_(realtime_period) {}
  ~RealtimeTestThread() override = default;

 private:
  RealtimeTestThread(const RealtimeTestThread&) = delete;
  RealtimeTestThread& operator=(const RealtimeTestThread&) = delete;

  TimeDelta GetRealtimePeriod() final { return realtime_period_; }

  // Verifies the realtime thead configuration.
  void RunTest() override {
    EXPECT_EQ(PlatformThread::GetCurrentThreadType(),
              ThreadType::kRealtimeAudio);

    mach_port_t mach_thread_id = pthread_mach_thread_np(
        PlatformThread::CurrentHandle().platform_handle());

    // |count| and |get_default| chosen impirically so that
    // time_constraints_buffer[0] would store the last constraints that were
    // applied.
    const int kPolicyCount = 32;
    thread_time_constraint_policy_data_t time_constraints_buffer[kPolicyCount];
    mach_msg_type_number_t count = kPolicyCount;
    boolean_t get_default = 0;

    kern_return_t result = thread_policy_get(
        mach_thread_id, THREAD_TIME_CONSTRAINT_POLICY,
        reinterpret_cast<thread_policy_t>(time_constraints_buffer), &count,
        &get_default);

    EXPECT_EQ(result, KERN_SUCCESS);

    const thread_time_constraint_policy_data_t& time_constraints =
        time_constraints_buffer[0];

    mach_timebase_info_data_t tb_info;
    mach_timebase_info(&tb_info);

    if (FeatureList::IsEnabled(kOptimizedRealtimeThreadingMac) &&
        !realtime_period_.is_zero()) {
      uint32_t abs_realtime_period = saturated_cast<uint32_t>(
          realtime_period_.InNanoseconds() *
          (static_cast<double>(tb_info.denom) / tb_info.numer));

      EXPECT_EQ(time_constraints.period, abs_realtime_period);
      EXPECT_EQ(
          time_constraints.computation,
          static_cast<uint32_t>(abs_realtime_period *
                                kOptimizedRealtimeThreadingMacBusy.Get()));
      EXPECT_EQ(
          time_constraints.constraint,
          static_cast<uint32_t>(abs_realtime_period *
                                kOptimizedRealtimeThreadingMacBusyLimit.Get()));
      EXPECT_EQ(time_constraints.preemptible,
                kOptimizedRealtimeThreadingMacPreemptible.Get());
    } else {
      // Old-style empirical values.
      const double kTimeQuantum = 2.9;
      const double kAudioTimeNeeded = 0.75 * kTimeQuantum;
      const double kMaxTimeAllowed = 0.85 * kTimeQuantum;

      // Get the conversion factor from milliseconds to absolute time
      // which is what the time-constraints returns.
      double ms_to_abs_time = double(tb_info.denom) / tb_info.numer * 1000000;

      EXPECT_EQ(time_constraints.period,
                saturated_cast<uint32_t>(kTimeQuantum * ms_to_abs_time));
      EXPECT_EQ(time_constraints.computation,
                saturated_cast<uint32_t>(kAudioTimeNeeded * ms_to_abs_time));
      EXPECT_EQ(time_constraints.constraint,
                saturated_cast<uint32_t>(kMaxTimeAllowed * ms_to_abs_time));
      EXPECT_FALSE(time_constraints.preemptible);
    }
  }

  const TimeDelta realtime_period_;
};

class RealtimePlatformThreadTest
    : public testing::TestWithParam<
          std::tuple<bool, FieldTrialParams, TimeDelta>> {
 protected:
  void VerifyRealtimeConfig(TimeDelta period) {
    RealtimeTestThread thread(period);
    PlatformThreadHandle handle;

    ASSERT_FALSE(thread.IsRunning());
    ASSERT_TRUE(PlatformThread::CreateWithType(0, &thread, &handle,
                                               ThreadType::kRealtimeAudio));
    thread.WaitForTerminationReady();
    ASSERT_TRUE(thread.IsRunning());

    thread.MarkForTermination();
    PlatformThread::Join(handle);
    ASSERT_FALSE(thread.IsRunning());
  }
};

TEST_P(RealtimePlatformThreadTest, RealtimeAudioConfigMac) {
  test::ScopedFeatureList feature_list;
  if (std::get<0>(GetParam())) {
    feature_list.InitAndEnableFeatureWithParameters(
        kOptimizedRealtimeThreadingMac, std::get<1>(GetParam()));
  } else {
    feature_list.InitAndDisableFeature(kOptimizedRealtimeThreadingMac);
  }

  PlatformThread::InitFeaturesPostFieldTrial();
  VerifyRealtimeConfig(std::get<2>(GetParam()));
}

INSTANTIATE_TEST_SUITE_P(
    RealtimePlatformThreadTest,
    RealtimePlatformThreadTest,
    testing::Combine(
        testing::Bool(),
        testing::Values(
            FieldTrialParams{
                {kOptimizedRealtimeThreadingMacPreemptible.name, "true"}},
            FieldTrialParams{
                {kOptimizedRealtimeThreadingMacPreemptible.name, "false"}},
            FieldTrialParams{
                {kOptimizedRealtimeThreadingMacBusy.name, "0.5"},
                {kOptimizedRealtimeThreadingMacBusyLimit.name, "0.75"}},
            FieldTrialParams{
                {kOptimizedRealtimeThreadingMacBusy.name, "0.7"},
                {kOptimizedRealtimeThreadingMacBusyLimit.name, "0.7"}},
            FieldTrialParams{
                {kOptimizedRealtimeThreadingMacBusy.name, "0.5"},
                {kOptimizedRealtimeThreadingMacBusyLimit.name, "1.0"}}),
        testing::Values(TimeDelta(),
                        Seconds(256.0 / 48000),
                        Milliseconds(5),
                        Milliseconds(10),
                        Seconds(1024.0 / 44100),
                        Seconds(1024.0 / 16000))));

}  // namespace

#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

namespace {

bool IsTidCacheCorrect() {
  return PlatformThread::CurrentId() == syscall(__NR_gettid);
}

void* CheckTidCacheCorrectWrapper(void*) {
  CHECK(IsTidCacheCorrect());
  return nullptr;
}

void CreatePthreadToCheckCache() {
  pthread_t thread_id;
  pthread_create(&thread_id, nullptr, CheckTidCacheCorrectWrapper, nullptr);
  pthread_join(thread_id, nullptr);
}

// This test must use raw pthreads and fork() to avoid calls from //base to
// PlatformThread::CurrentId(), as the ordering of calls is important to the
// test.
void TestTidCacheCorrect(bool main_thread_accesses_cache_first) {
  EXPECT_TRUE(IsTidCacheCorrect());

  CreatePthreadToCheckCache();

  // Now fork a process and make sure the TID cache gets correctly updated on
  // both its main thread and a child thread.
  pid_t child_pid = fork();
  ASSERT_GE(child_pid, 0);

  if (child_pid == 0) {
    // In the child.
    if (main_thread_accesses_cache_first) {
      if (!IsTidCacheCorrect())
        _exit(1);
    }

    // Access the TID cache on another thread and make sure the cached value is
    // correct.
    CreatePthreadToCheckCache();

    if (!main_thread_accesses_cache_first) {
      // Make sure the main thread's cache is correct even though another thread
      // accessed the cache first.
      if (!IsTidCacheCorrect())
        _exit(1);
    }

    _exit(0);
  }

  int status;
  ASSERT_EQ(waitpid(child_pid, &status, 0), child_pid);
  ASSERT_TRUE(WIFEXITED(status));
  ASSERT_EQ(WEXITSTATUS(status), 0);
}

TEST(PlatformThreadTidCacheTest, MainThreadFirst) {
  TestTidCacheCorrect(true);
}

TEST(PlatformThreadTidCacheTest, MainThreadSecond) {
  TestTidCacheCorrect(false);
}

}  // namespace

#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

}  // namespace base
