chromium/base/threading/platform_thread.h

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

// WARNING: You should *NOT* be using this class directly.  PlatformThread is
// the low-level platform-specific abstraction to the OS's threading interface.
// You should instead be using a message-loop driven Thread, see thread.h.

#ifndef BASE_THREADING_PLATFORM_THREAD_H_
#define BASE_THREADING_PLATFORM_THREAD_H_

#include <stddef.h>

#include <iosfwd>
#include <optional>
#include <type_traits>

#include "base/base_export.h"
#include "base/message_loop/message_pump_type.h"
#include "base/process/process_handle.h"
#include "base/sequence_checker_impl.h"
#include "base/threading/platform_thread_ref.h"
#include "base/time/time.h"
#include "base/types/strong_alias.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"

#if BUILDFLAG(IS_WIN)
#include "base/win/windows_types.h"
#elif BUILDFLAG(IS_FUCHSIA)
#include <zircon/types.h>
#elif BUILDFLAG(IS_APPLE)
#include <mach/mach_types.h>
#elif BUILDFLAG(IS_POSIX)
#include <pthread.h>
#include <unistd.h>
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "base/feature_list.h"
#endif

namespace base {

// Used for logging. Always an integer value.
#if BUILDFLAG(IS_WIN)
typedef DWORD PlatformThreadId;
#elif BUILDFLAG(IS_FUCHSIA)
typedef zx_koid_t PlatformThreadId;
#elif BUILDFLAG(IS_APPLE)
typedef mach_port_t PlatformThreadId;
#elif BUILDFLAG(IS_POSIX)
PlatformThreadId;
#endif
static_assert;

// Used to operate on threads.
class PlatformThreadHandle {};

const PlatformThreadId kInvalidThreadId(0);

// Valid values for `thread_type` of Thread::Options, SimpleThread::Options,
// and SetCurrentThreadType(), listed in increasing order of importance.
//
// It is up to each platform-specific implementation what these translate to.
// Callers should avoid setting different ThreadTypes on different platforms
// (ifdefs) at all cost, instead the platform differences should be encoded in
// the platform-specific implementations. Some implementations may treat
// adjacent ThreadTypes in this enum as equivalent.
//
// Reach out to //base/task/OWNERS ([email protected]) before changing
// thread type assignments in your component, as such decisions affect the whole
// of Chrome.
//
// Refer to PlatformThreadTest.SetCurrentThreadTypeTest in
// platform_thread_unittest.cc for the most up-to-date state of each platform's
// handling of ThreadType.
enum class ThreadType : int {};

// Cross-platform mapping of physical thread priorities. Used by tests to verify
// the underlying effects of SetCurrentThreadType.
enum class ThreadPriorityForTest : int {};

// A namespace for low-level thread functions.
class BASE_EXPORT PlatformThreadBase {};

#if BUILDFLAG(IS_APPLE)
class BASE_EXPORT PlatformThreadApple : public PlatformThreadBase {
 public:
  // Stores the period value in TLS.
  static void SetCurrentThreadRealtimePeriodValue(TimeDelta realtime_period);

  static TimeDelta GetCurrentThreadRealtimePeriodForTest();

  // Initializes features for this class. See `base::features::Init()`.
  static void InitializeFeatures();
};
#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
class ThreadTypeDelegate;
IsViaIPC;

class BASE_EXPORT PlatformThreadLinux : public PlatformThreadBase {};
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

#if BUILDFLAG(IS_CHROMEOS)
BASE_EXPORT BASE_DECLARE_FEATURE(kSetRtForDisplayThreads);

class CrossProcessPlatformThreadDelegate;

class BASE_EXPORT PlatformThreadChromeOS : public PlatformThreadLinux {
 public:
  // Sets a delegate which handles thread type changes for threads of another
  // process. This must be externally synchronized with any call to
  // SetCurrentThreadType.
  static void SetCrossProcessPlatformThreadDelegate(
      CrossProcessPlatformThreadDelegate* delegate);

  // Initializes features for this class. See `base::features::Init()`.
  static void InitializeFeatures();

  // Toggles a specific thread's type at runtime. This is the ChromeOS-specific
  // version and includes Linux's functionality but does slightly more. See
  // PlatformThreadLinux's SetThreadType() header comment for Linux details.
  static void SetThreadType(PlatformThreadId process_id,
                            PlatformThreadId thread_id,
                            ThreadType thread_type,
                            IsViaIPC via_ipc);

  // Returns true if the feature for backgrounding of threads is enabled.
  static bool IsThreadsBgFeatureEnabled();

  // Returns true if the feature for setting display threads to RT is enabled.
  static bool IsDisplayThreadsRtFeatureEnabled();

  // Set a specific thread as backgrounded. This is called when the process
  // moves to and from the background and changes have to be made to each of its
  // thread's scheduling attributes.
  static void SetThreadBackgrounded(ProcessId process_id,
                                    PlatformThreadId thread_id,
                                    bool backgrounded);

  // Returns the thread type of a thread given its thread id.
  static std::optional<ThreadType> GetThreadTypeFromThreadId(
      ProcessId process_id,
      PlatformThreadId thread_id);

  // Returns a SequenceChecker which should be used to verify that all
  // cross-process priority changes are performed without races.
  static SequenceCheckerImpl& GetCrossProcessThreadPrioritySequenceChecker();
};
#endif  // BUILDFLAG(IS_CHROMEOS)

// Alias to the correct platform-specific class based on preprocessor directives
#if BUILDFLAG(IS_APPLE)
using PlatformThread = PlatformThreadApple;
#elif BUILDFLAG(IS_CHROMEOS)
using PlatformThread = PlatformThreadChromeOS;
#elif BUILDFLAG(IS_LINUX)
PlatformThread;
#else
using PlatformThread = PlatformThreadBase;
#endif

namespace internal {

void SetCurrentThreadType(ThreadType thread_type,
                          MessagePumpType pump_type_hint);

void SetCurrentThreadTypeImpl(ThreadType thread_type,
                              MessagePumpType pump_type_hint);

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
void SetThreadTypeLinux(PlatformThreadId process_id,
                        PlatformThreadId thread_id,
                        ThreadType thread_type,
                        IsViaIPC via_ipc);
#endif
#if BUILDFLAG(IS_CHROMEOS)
void SetThreadTypeChromeOS(PlatformThreadId process_id,
                           PlatformThreadId thread_id,
                           ThreadType thread_type,
                           IsViaIPC via_ipc);
#endif
#if BUILDFLAG(IS_CHROMEOS)
inline constexpr auto SetThreadType = SetThreadTypeChromeOS;
#elif BUILDFLAG(IS_LINUX)
inline constexpr auto SetThreadType =;
#endif

}  // namespace internal

}  // namespace base

#endif  // BASE_THREADING_PLATFORM_THREAD_H_