1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker // WARNING: You should *NOT* be using this class directly. PlatformThread is 6*6777b538SAndroid Build Coastguard Worker // the low-level platform-specific abstraction to the OS's threading interface. 7*6777b538SAndroid Build Coastguard Worker // You should instead be using a message-loop driven Thread, see thread.h. 8*6777b538SAndroid Build Coastguard Worker 9*6777b538SAndroid Build Coastguard Worker #ifndef BASE_THREADING_PLATFORM_THREAD_H_ 10*6777b538SAndroid Build Coastguard Worker #define BASE_THREADING_PLATFORM_THREAD_H_ 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker #include <stddef.h> 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker #include <iosfwd> 15*6777b538SAndroid Build Coastguard Worker #include <optional> 16*6777b538SAndroid Build Coastguard Worker #include <type_traits> 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 19*6777b538SAndroid Build Coastguard Worker #include "base/feature_list.h" 20*6777b538SAndroid Build Coastguard Worker #include "base/message_loop/message_pump_type.h" 21*6777b538SAndroid Build Coastguard Worker #include "base/process/process_handle.h" 22*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker_impl.h" 23*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread_ref.h" 24*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 25*6777b538SAndroid Build Coastguard Worker #include "base/types/strong_alias.h" 26*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h" 27*6777b538SAndroid Build Coastguard Worker #include "build/chromeos_buildflags.h" 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) 30*6777b538SAndroid Build Coastguard Worker #include "base/win/windows_types.h" 31*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FUCHSIA) 32*6777b538SAndroid Build Coastguard Worker #include <zircon/types.h> 33*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_APPLE) 34*6777b538SAndroid Build Coastguard Worker #include <mach/mach_types.h> 35*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) 36*6777b538SAndroid Build Coastguard Worker #include <pthread.h> 37*6777b538SAndroid Build Coastguard Worker #include <unistd.h> 38*6777b538SAndroid Build Coastguard Worker #endif 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker namespace base { 41*6777b538SAndroid Build Coastguard Worker 42*6777b538SAndroid Build Coastguard Worker // Used for logging. Always an integer value. 43*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) 44*6777b538SAndroid Build Coastguard Worker typedef DWORD PlatformThreadId; 45*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_FUCHSIA) 46*6777b538SAndroid Build Coastguard Worker typedef zx_koid_t PlatformThreadId; 47*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_APPLE) 48*6777b538SAndroid Build Coastguard Worker typedef mach_port_t PlatformThreadId; 49*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) 50*6777b538SAndroid Build Coastguard Worker typedef pid_t PlatformThreadId; 51*6777b538SAndroid Build Coastguard Worker #endif 52*6777b538SAndroid Build Coastguard Worker static_assert(std::is_integral_v<PlatformThreadId>, "Always an integer value."); 53*6777b538SAndroid Build Coastguard Worker 54*6777b538SAndroid Build Coastguard Worker // Used to operate on threads. 55*6777b538SAndroid Build Coastguard Worker class PlatformThreadHandle { 56*6777b538SAndroid Build Coastguard Worker public: 57*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN) 58*6777b538SAndroid Build Coastguard Worker typedef void* Handle; 59*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) 60*6777b538SAndroid Build Coastguard Worker typedef pthread_t Handle; 61*6777b538SAndroid Build Coastguard Worker #endif 62*6777b538SAndroid Build Coastguard Worker PlatformThreadHandle()63*6777b538SAndroid Build Coastguard Worker constexpr PlatformThreadHandle() : handle_(0) {} 64*6777b538SAndroid Build Coastguard Worker PlatformThreadHandle(Handle handle)65*6777b538SAndroid Build Coastguard Worker explicit constexpr PlatformThreadHandle(Handle handle) : handle_(handle) {} 66*6777b538SAndroid Build Coastguard Worker is_equal(const PlatformThreadHandle & other)67*6777b538SAndroid Build Coastguard Worker bool is_equal(const PlatformThreadHandle& other) const { 68*6777b538SAndroid Build Coastguard Worker return handle_ == other.handle_; 69*6777b538SAndroid Build Coastguard Worker } 70*6777b538SAndroid Build Coastguard Worker is_null()71*6777b538SAndroid Build Coastguard Worker bool is_null() const { 72*6777b538SAndroid Build Coastguard Worker return !handle_; 73*6777b538SAndroid Build Coastguard Worker } 74*6777b538SAndroid Build Coastguard Worker platform_handle()75*6777b538SAndroid Build Coastguard Worker Handle platform_handle() const { 76*6777b538SAndroid Build Coastguard Worker return handle_; 77*6777b538SAndroid Build Coastguard Worker } 78*6777b538SAndroid Build Coastguard Worker 79*6777b538SAndroid Build Coastguard Worker private: 80*6777b538SAndroid Build Coastguard Worker Handle handle_; 81*6777b538SAndroid Build Coastguard Worker }; 82*6777b538SAndroid Build Coastguard Worker 83*6777b538SAndroid Build Coastguard Worker const PlatformThreadId kInvalidThreadId(0); 84*6777b538SAndroid Build Coastguard Worker 85*6777b538SAndroid Build Coastguard Worker // Valid values for `thread_type` of Thread::Options, SimpleThread::Options, 86*6777b538SAndroid Build Coastguard Worker // and SetCurrentThreadType(), listed in increasing order of importance. 87*6777b538SAndroid Build Coastguard Worker // 88*6777b538SAndroid Build Coastguard Worker // It is up to each platform-specific implementation what these translate to. 89*6777b538SAndroid Build Coastguard Worker // Callers should avoid setting different ThreadTypes on different platforms 90*6777b538SAndroid Build Coastguard Worker // (ifdefs) at all cost, instead the platform differences should be encoded in 91*6777b538SAndroid Build Coastguard Worker // the platform-specific implementations. Some implementations may treat 92*6777b538SAndroid Build Coastguard Worker // adjacent ThreadTypes in this enum as equivalent. 93*6777b538SAndroid Build Coastguard Worker // 94*6777b538SAndroid Build Coastguard Worker // Reach out to //base/task/OWNERS ([email protected]) before changing 95*6777b538SAndroid Build Coastguard Worker // thread type assignments in your component, as such decisions affect the whole 96*6777b538SAndroid Build Coastguard Worker // of Chrome. 97*6777b538SAndroid Build Coastguard Worker // 98*6777b538SAndroid Build Coastguard Worker // Refer to PlatformThreadTest.SetCurrentThreadTypeTest in 99*6777b538SAndroid Build Coastguard Worker // platform_thread_unittest.cc for the most up-to-date state of each platform's 100*6777b538SAndroid Build Coastguard Worker // handling of ThreadType. 101*6777b538SAndroid Build Coastguard Worker enum class ThreadType : int { 102*6777b538SAndroid Build Coastguard Worker // Suitable for threads that have the least urgency and lowest priority, and 103*6777b538SAndroid Build Coastguard Worker // can be interrupted or delayed by other types. 104*6777b538SAndroid Build Coastguard Worker kBackground, 105*6777b538SAndroid Build Coastguard Worker // Suitable for threads that are less important than normal type, and can be 106*6777b538SAndroid Build Coastguard Worker // interrupted or delayed by threads with kDefault type. 107*6777b538SAndroid Build Coastguard Worker kUtility, 108*6777b538SAndroid Build Coastguard Worker // Suitable for threads that produce user-visible artifacts but aren't 109*6777b538SAndroid Build Coastguard Worker // latency sensitive. The underlying platform will try to be economic 110*6777b538SAndroid Build Coastguard Worker // in its usage of resources for this thread, if possible. 111*6777b538SAndroid Build Coastguard Worker kResourceEfficient, 112*6777b538SAndroid Build Coastguard Worker // Default type. The thread priority or quality of service will be set to 113*6777b538SAndroid Build Coastguard Worker // platform default. In Chrome, this is suitable for handling user 114*6777b538SAndroid Build Coastguard Worker // interactions (input), only display and audio can get a higher priority. 115*6777b538SAndroid Build Coastguard Worker kDefault, 116*6777b538SAndroid Build Coastguard Worker // Suitable for threads which are critical to compositing the foreground 117*6777b538SAndroid Build Coastguard Worker // content. 118*6777b538SAndroid Build Coastguard Worker kCompositing, 119*6777b538SAndroid Build Coastguard Worker // Suitable for display critical threads. 120*6777b538SAndroid Build Coastguard Worker kDisplayCritical, 121*6777b538SAndroid Build Coastguard Worker // Suitable for low-latency, glitch-resistant audio. 122*6777b538SAndroid Build Coastguard Worker kRealtimeAudio, 123*6777b538SAndroid Build Coastguard Worker kMaxValue = kRealtimeAudio, 124*6777b538SAndroid Build Coastguard Worker }; 125*6777b538SAndroid Build Coastguard Worker 126*6777b538SAndroid Build Coastguard Worker // Cross-platform mapping of physical thread priorities. Used by tests to verify 127*6777b538SAndroid Build Coastguard Worker // the underlying effects of SetCurrentThreadType. 128*6777b538SAndroid Build Coastguard Worker enum class ThreadPriorityForTest : int { 129*6777b538SAndroid Build Coastguard Worker kBackground, 130*6777b538SAndroid Build Coastguard Worker kUtility, 131*6777b538SAndroid Build Coastguard Worker kResourceEfficient, 132*6777b538SAndroid Build Coastguard Worker kNormal, 133*6777b538SAndroid Build Coastguard Worker kCompositing, 134*6777b538SAndroid Build Coastguard Worker kDisplay, 135*6777b538SAndroid Build Coastguard Worker kRealtimeAudio, 136*6777b538SAndroid Build Coastguard Worker kMaxValue = kRealtimeAudio, 137*6777b538SAndroid Build Coastguard Worker }; 138*6777b538SAndroid Build Coastguard Worker 139*6777b538SAndroid Build Coastguard Worker // A namespace for low-level thread functions. 140*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT PlatformThreadBase { 141*6777b538SAndroid Build Coastguard Worker public: 142*6777b538SAndroid Build Coastguard Worker // Implement this interface to run code on a background thread. Your 143*6777b538SAndroid Build Coastguard Worker // ThreadMain method will be called on the newly created thread. 144*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT Delegate { 145*6777b538SAndroid Build Coastguard Worker public: 146*6777b538SAndroid Build Coastguard Worker virtual void ThreadMain() = 0; 147*6777b538SAndroid Build Coastguard Worker 148*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE) 149*6777b538SAndroid Build Coastguard Worker // TODO: Move this to the PlatformThreadApple class. 150*6777b538SAndroid Build Coastguard Worker // The interval at which the thread expects to have work to do. Zero if 151*6777b538SAndroid Build Coastguard Worker // unknown. (Example: audio buffer duration for real-time audio.) Is used to 152*6777b538SAndroid Build Coastguard Worker // optimize the thread real-time behavior. Is called on the newly created 153*6777b538SAndroid Build Coastguard Worker // thread before ThreadMain(). 154*6777b538SAndroid Build Coastguard Worker virtual TimeDelta GetRealtimePeriod(); 155*6777b538SAndroid Build Coastguard Worker #endif 156*6777b538SAndroid Build Coastguard Worker 157*6777b538SAndroid Build Coastguard Worker protected: 158*6777b538SAndroid Build Coastguard Worker virtual ~Delegate() = default; 159*6777b538SAndroid Build Coastguard Worker }; 160*6777b538SAndroid Build Coastguard Worker 161*6777b538SAndroid Build Coastguard Worker PlatformThreadBase() = delete; 162*6777b538SAndroid Build Coastguard Worker PlatformThreadBase(const PlatformThreadBase&) = delete; 163*6777b538SAndroid Build Coastguard Worker PlatformThreadBase& operator=(const PlatformThreadBase&) = delete; 164*6777b538SAndroid Build Coastguard Worker 165*6777b538SAndroid Build Coastguard Worker // Gets the current thread id, which may be useful for logging purposes. 166*6777b538SAndroid Build Coastguard Worker static PlatformThreadId CurrentId(); 167*6777b538SAndroid Build Coastguard Worker 168*6777b538SAndroid Build Coastguard Worker // Gets the current thread reference, which can be used to check if 169*6777b538SAndroid Build Coastguard Worker // we're on the right thread quickly. 170*6777b538SAndroid Build Coastguard Worker static PlatformThreadRef CurrentRef(); 171*6777b538SAndroid Build Coastguard Worker 172*6777b538SAndroid Build Coastguard Worker // Get the handle representing the current thread. On Windows, this is a 173*6777b538SAndroid Build Coastguard Worker // pseudo handle constant which will always represent the thread using it and 174*6777b538SAndroid Build Coastguard Worker // hence should not be shared with other threads nor be used to differentiate 175*6777b538SAndroid Build Coastguard Worker // the current thread from another. 176*6777b538SAndroid Build Coastguard Worker static PlatformThreadHandle CurrentHandle(); 177*6777b538SAndroid Build Coastguard Worker 178*6777b538SAndroid Build Coastguard Worker // Yield the current thread so another thread can be scheduled. 179*6777b538SAndroid Build Coastguard Worker // 180*6777b538SAndroid Build Coastguard Worker // Note: this is likely not the right call to make in most situations. If this 181*6777b538SAndroid Build Coastguard Worker // is part of a spin loop, consider base::Lock, which likely has better tail 182*6777b538SAndroid Build Coastguard Worker // latency. Yielding the thread has different effects depending on the 183*6777b538SAndroid Build Coastguard Worker // platform, system load, etc., and can result in yielding the CPU for less 184*6777b538SAndroid Build Coastguard Worker // than 1us, or many tens of ms. 185*6777b538SAndroid Build Coastguard Worker static void YieldCurrentThread(); 186*6777b538SAndroid Build Coastguard Worker 187*6777b538SAndroid Build Coastguard Worker // Sleeps for the specified duration (real-time; ignores time overrides). 188*6777b538SAndroid Build Coastguard Worker // Note: The sleep duration may be in base::Time or base::TimeTicks, depending 189*6777b538SAndroid Build Coastguard Worker // on platform. If you're looking to use this in unit tests testing delayed 190*6777b538SAndroid Build Coastguard Worker // tasks, this will be unreliable - instead, use 191*6777b538SAndroid Build Coastguard Worker // base::test::TaskEnvironment with MOCK_TIME mode. 192*6777b538SAndroid Build Coastguard Worker static void Sleep(base::TimeDelta duration); 193*6777b538SAndroid Build Coastguard Worker 194*6777b538SAndroid Build Coastguard Worker // Sets the thread name visible to debuggers/tools. This will try to 195*6777b538SAndroid Build Coastguard Worker // initialize the context for current thread unless it's a WorkerThread. 196*6777b538SAndroid Build Coastguard Worker static void SetName(const std::string& name); 197*6777b538SAndroid Build Coastguard Worker 198*6777b538SAndroid Build Coastguard Worker // Gets the thread name, if previously set by SetName. 199*6777b538SAndroid Build Coastguard Worker static const char* GetName(); 200*6777b538SAndroid Build Coastguard Worker 201*6777b538SAndroid Build Coastguard Worker // Creates a new thread. The `stack_size` parameter can be 0 to indicate 202*6777b538SAndroid Build Coastguard Worker // that the default stack size should be used. Upon success, 203*6777b538SAndroid Build Coastguard Worker // `*thread_handle` will be assigned a handle to the newly created thread, 204*6777b538SAndroid Build Coastguard Worker // and `delegate`'s ThreadMain method will be executed on the newly created 205*6777b538SAndroid Build Coastguard Worker // thread. 206*6777b538SAndroid Build Coastguard Worker // NOTE: When you are done with the thread handle, you must call Join to 207*6777b538SAndroid Build Coastguard Worker // release system resources associated with the thread. You must ensure that 208*6777b538SAndroid Build Coastguard Worker // the Delegate object outlives the thread. Create(size_t stack_size,Delegate * delegate,PlatformThreadHandle * thread_handle)209*6777b538SAndroid Build Coastguard Worker static bool Create(size_t stack_size, 210*6777b538SAndroid Build Coastguard Worker Delegate* delegate, 211*6777b538SAndroid Build Coastguard Worker PlatformThreadHandle* thread_handle) { 212*6777b538SAndroid Build Coastguard Worker return CreateWithType(stack_size, delegate, thread_handle, 213*6777b538SAndroid Build Coastguard Worker ThreadType::kDefault); 214*6777b538SAndroid Build Coastguard Worker } 215*6777b538SAndroid Build Coastguard Worker 216*6777b538SAndroid Build Coastguard Worker // CreateWithType() does the same thing as Create() except the priority and 217*6777b538SAndroid Build Coastguard Worker // possibly the QoS of the thread is set based on `thread_type`. 218*6777b538SAndroid Build Coastguard Worker // `pump_type_hint` must be provided if the thread will be using a 219*6777b538SAndroid Build Coastguard Worker // MessagePumpForUI or MessagePumpForIO as this affects the application of 220*6777b538SAndroid Build Coastguard Worker // `thread_type`. 221*6777b538SAndroid Build Coastguard Worker static bool CreateWithType( 222*6777b538SAndroid Build Coastguard Worker size_t stack_size, 223*6777b538SAndroid Build Coastguard Worker Delegate* delegate, 224*6777b538SAndroid Build Coastguard Worker PlatformThreadHandle* thread_handle, 225*6777b538SAndroid Build Coastguard Worker ThreadType thread_type, 226*6777b538SAndroid Build Coastguard Worker MessagePumpType pump_type_hint = MessagePumpType::DEFAULT); 227*6777b538SAndroid Build Coastguard Worker 228*6777b538SAndroid Build Coastguard Worker // CreateNonJoinable() does the same thing as Create() except the thread 229*6777b538SAndroid Build Coastguard Worker // cannot be Join()'d. Therefore, it also does not output a 230*6777b538SAndroid Build Coastguard Worker // PlatformThreadHandle. 231*6777b538SAndroid Build Coastguard Worker static bool CreateNonJoinable(size_t stack_size, Delegate* delegate); 232*6777b538SAndroid Build Coastguard Worker 233*6777b538SAndroid Build Coastguard Worker // CreateNonJoinableWithType() does the same thing as CreateNonJoinable() 234*6777b538SAndroid Build Coastguard Worker // except the type of the thread is set based on `type`. `pump_type_hint` must 235*6777b538SAndroid Build Coastguard Worker // be provided if the thread will be using a MessagePumpForUI or 236*6777b538SAndroid Build Coastguard Worker // MessagePumpForIO as this affects the application of `thread_type`. 237*6777b538SAndroid Build Coastguard Worker static bool CreateNonJoinableWithType( 238*6777b538SAndroid Build Coastguard Worker size_t stack_size, 239*6777b538SAndroid Build Coastguard Worker Delegate* delegate, 240*6777b538SAndroid Build Coastguard Worker ThreadType thread_type, 241*6777b538SAndroid Build Coastguard Worker MessagePumpType pump_type_hint = MessagePumpType::DEFAULT); 242*6777b538SAndroid Build Coastguard Worker 243*6777b538SAndroid Build Coastguard Worker // Joins with a thread created via the Create function. This function blocks 244*6777b538SAndroid Build Coastguard Worker // the caller until the designated thread exits. This will invalidate 245*6777b538SAndroid Build Coastguard Worker // `thread_handle`. 246*6777b538SAndroid Build Coastguard Worker static void Join(PlatformThreadHandle thread_handle); 247*6777b538SAndroid Build Coastguard Worker 248*6777b538SAndroid Build Coastguard Worker // Detaches and releases the thread handle. The thread is no longer joinable 249*6777b538SAndroid Build Coastguard Worker // and `thread_handle` is invalidated after this call. 250*6777b538SAndroid Build Coastguard Worker static void Detach(PlatformThreadHandle thread_handle); 251*6777b538SAndroid Build Coastguard Worker 252*6777b538SAndroid Build Coastguard Worker // Returns true if SetCurrentThreadType() should be able to change the type 253*6777b538SAndroid Build Coastguard Worker // of a thread in current process from `from` to `to`. 254*6777b538SAndroid Build Coastguard Worker static bool CanChangeThreadType(ThreadType from, ThreadType to); 255*6777b538SAndroid Build Coastguard Worker 256*6777b538SAndroid Build Coastguard Worker // Declares the type of work running on the current thread. This will affect 257*6777b538SAndroid Build Coastguard Worker // things like thread priority and thread QoS (Quality of Service) to the best 258*6777b538SAndroid Build Coastguard Worker // of the current platform's abilities. 259*6777b538SAndroid Build Coastguard Worker static void SetCurrentThreadType(ThreadType thread_type); 260*6777b538SAndroid Build Coastguard Worker 261*6777b538SAndroid Build Coastguard Worker // Get the last `thread_type` set by SetCurrentThreadType, no matter if the 262*6777b538SAndroid Build Coastguard Worker // underlying priority successfully changed or not. 263*6777b538SAndroid Build Coastguard Worker static ThreadType GetCurrentThreadType(); 264*6777b538SAndroid Build Coastguard Worker 265*6777b538SAndroid Build Coastguard Worker // Returns a realtime period provided by `delegate`. 266*6777b538SAndroid Build Coastguard Worker static TimeDelta GetRealtimePeriod(Delegate* delegate); 267*6777b538SAndroid Build Coastguard Worker 268*6777b538SAndroid Build Coastguard Worker // Returns the override of task leeway if any. 269*6777b538SAndroid Build Coastguard Worker static std::optional<TimeDelta> GetThreadLeewayOverride(); 270*6777b538SAndroid Build Coastguard Worker 271*6777b538SAndroid Build Coastguard Worker // Returns the default thread stack size set by chrome. If we do not 272*6777b538SAndroid Build Coastguard Worker // explicitly set default size then returns 0. 273*6777b538SAndroid Build Coastguard Worker static size_t GetDefaultThreadStackSize(); 274*6777b538SAndroid Build Coastguard Worker 275*6777b538SAndroid Build Coastguard Worker static ThreadPriorityForTest GetCurrentThreadPriorityForTest(); 276*6777b538SAndroid Build Coastguard Worker 277*6777b538SAndroid Build Coastguard Worker protected: 278*6777b538SAndroid Build Coastguard Worker static void SetNameCommon(const std::string& name); 279*6777b538SAndroid Build Coastguard Worker }; 280*6777b538SAndroid Build Coastguard Worker 281*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE) 282*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT PlatformThreadApple : public PlatformThreadBase { 283*6777b538SAndroid Build Coastguard Worker public: 284*6777b538SAndroid Build Coastguard Worker // Stores the period value in TLS. 285*6777b538SAndroid Build Coastguard Worker static void SetCurrentThreadRealtimePeriodValue(TimeDelta realtime_period); 286*6777b538SAndroid Build Coastguard Worker 287*6777b538SAndroid Build Coastguard Worker static TimeDelta GetCurrentThreadRealtimePeriodForTest(); 288*6777b538SAndroid Build Coastguard Worker 289*6777b538SAndroid Build Coastguard Worker // Initializes features for this class. See `base::features::Init()`. 290*6777b538SAndroid Build Coastguard Worker static void InitializeFeatures(); 291*6777b538SAndroid Build Coastguard Worker }; 292*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_APPLE) 293*6777b538SAndroid Build Coastguard Worker 294*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 295*6777b538SAndroid Build Coastguard Worker class ThreadTypeDelegate; 296*6777b538SAndroid Build Coastguard Worker using IsViaIPC = base::StrongAlias<class IsViaIPCTag, bool>; 297*6777b538SAndroid Build Coastguard Worker 298*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT PlatformThreadLinux : public PlatformThreadBase { 299*6777b538SAndroid Build Coastguard Worker public: 300*6777b538SAndroid Build Coastguard Worker static constexpr struct sched_param kRealTimeAudioPrio = {8}; 301*6777b538SAndroid Build Coastguard Worker static constexpr struct sched_param kRealTimeDisplayPrio = {6}; 302*6777b538SAndroid Build Coastguard Worker 303*6777b538SAndroid Build Coastguard Worker // Sets a delegate which handles thread type changes for this process. This 304*6777b538SAndroid Build Coastguard Worker // must be externally synchronized with any call to SetCurrentThreadType. 305*6777b538SAndroid Build Coastguard Worker static void SetThreadTypeDelegate(ThreadTypeDelegate* delegate); 306*6777b538SAndroid Build Coastguard Worker 307*6777b538SAndroid Build Coastguard Worker // Toggles a specific thread's type at runtime. This can be used to 308*6777b538SAndroid Build Coastguard Worker // change the priority of a thread in a different process and will fail 309*6777b538SAndroid Build Coastguard Worker // if the calling process does not have proper permissions. The 310*6777b538SAndroid Build Coastguard Worker // SetCurrentThreadType() function above is preferred in favor of 311*6777b538SAndroid Build Coastguard Worker // security but on platforms where sandboxed processes are not allowed to 312*6777b538SAndroid Build Coastguard Worker // change priority this function exists to allow a non-sandboxed process 313*6777b538SAndroid Build Coastguard Worker // to change the priority of sandboxed threads for improved performance. 314*6777b538SAndroid Build Coastguard Worker // Warning: Don't use this for a main thread because that will change the 315*6777b538SAndroid Build Coastguard Worker // whole thread group's (i.e. process) priority. 316*6777b538SAndroid Build Coastguard Worker static void SetThreadType(PlatformThreadId process_id, 317*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id, 318*6777b538SAndroid Build Coastguard Worker ThreadType thread_type, 319*6777b538SAndroid Build Coastguard Worker IsViaIPC via_ipc); 320*6777b538SAndroid Build Coastguard Worker 321*6777b538SAndroid Build Coastguard Worker // Toggles a specific thread's type at runtime. The thread must be of the 322*6777b538SAndroid Build Coastguard Worker // current process. 323*6777b538SAndroid Build Coastguard Worker static void SetThreadType(PlatformThreadId thread_id, ThreadType thread_type); 324*6777b538SAndroid Build Coastguard Worker 325*6777b538SAndroid Build Coastguard Worker // For a given thread id and thread type, setup the cpuset and schedtune 326*6777b538SAndroid Build Coastguard Worker // CGroups for the thread. 327*6777b538SAndroid Build Coastguard Worker static void SetThreadCgroupsForThreadType(PlatformThreadId thread_id, 328*6777b538SAndroid Build Coastguard Worker ThreadType thread_type); 329*6777b538SAndroid Build Coastguard Worker 330*6777b538SAndroid Build Coastguard Worker // Determine if thread_id is a background thread by looking up whether 331*6777b538SAndroid Build Coastguard Worker // it is in the urgent or non-urgent cpuset 332*6777b538SAndroid Build Coastguard Worker static bool IsThreadBackgroundedForTest(PlatformThreadId thread_id); 333*6777b538SAndroid Build Coastguard Worker 334*6777b538SAndroid Build Coastguard Worker protected: 335*6777b538SAndroid Build Coastguard Worker static void SetThreadTypeInternal(PlatformThreadId process_id, 336*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id, 337*6777b538SAndroid Build Coastguard Worker ThreadType thread_type, 338*6777b538SAndroid Build Coastguard Worker IsViaIPC via_ipc); 339*6777b538SAndroid Build Coastguard Worker }; 340*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) 341*6777b538SAndroid Build Coastguard Worker 342*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_CHROMEOS) 343*6777b538SAndroid Build Coastguard Worker BASE_EXPORT BASE_DECLARE_FEATURE(kSetRtForDisplayThreads); 344*6777b538SAndroid Build Coastguard Worker 345*6777b538SAndroid Build Coastguard Worker class CrossProcessPlatformThreadDelegate; 346*6777b538SAndroid Build Coastguard Worker 347*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT PlatformThreadChromeOS : public PlatformThreadLinux { 348*6777b538SAndroid Build Coastguard Worker public: 349*6777b538SAndroid Build Coastguard Worker // Sets a delegate which handles thread type changes for threads of another 350*6777b538SAndroid Build Coastguard Worker // process. This must be externally synchronized with any call to 351*6777b538SAndroid Build Coastguard Worker // SetCurrentThreadType. 352*6777b538SAndroid Build Coastguard Worker static void SetCrossProcessPlatformThreadDelegate( 353*6777b538SAndroid Build Coastguard Worker CrossProcessPlatformThreadDelegate* delegate); 354*6777b538SAndroid Build Coastguard Worker 355*6777b538SAndroid Build Coastguard Worker // Initializes features for this class. See `base::features::Init()`. 356*6777b538SAndroid Build Coastguard Worker static void InitializeFeatures(); 357*6777b538SAndroid Build Coastguard Worker 358*6777b538SAndroid Build Coastguard Worker // Toggles a specific thread's type at runtime. This is the ChromeOS-specific 359*6777b538SAndroid Build Coastguard Worker // version and includes Linux's functionality but does slightly more. See 360*6777b538SAndroid Build Coastguard Worker // PlatformThreadLinux's SetThreadType() header comment for Linux details. 361*6777b538SAndroid Build Coastguard Worker static void SetThreadType(PlatformThreadId process_id, 362*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id, 363*6777b538SAndroid Build Coastguard Worker ThreadType thread_type, 364*6777b538SAndroid Build Coastguard Worker IsViaIPC via_ipc); 365*6777b538SAndroid Build Coastguard Worker 366*6777b538SAndroid Build Coastguard Worker // Returns true if the feature for backgrounding of threads is enabled. 367*6777b538SAndroid Build Coastguard Worker static bool IsThreadsBgFeatureEnabled(); 368*6777b538SAndroid Build Coastguard Worker 369*6777b538SAndroid Build Coastguard Worker // Returns true if the feature for setting display threads to RT is enabled. 370*6777b538SAndroid Build Coastguard Worker static bool IsDisplayThreadsRtFeatureEnabled(); 371*6777b538SAndroid Build Coastguard Worker 372*6777b538SAndroid Build Coastguard Worker // Set a specific thread as backgrounded. This is called when the process 373*6777b538SAndroid Build Coastguard Worker // moves to and from the background and changes have to be made to each of its 374*6777b538SAndroid Build Coastguard Worker // thread's scheduling attributes. 375*6777b538SAndroid Build Coastguard Worker static void SetThreadBackgrounded(ProcessId process_id, 376*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id, 377*6777b538SAndroid Build Coastguard Worker bool backgrounded); 378*6777b538SAndroid Build Coastguard Worker 379*6777b538SAndroid Build Coastguard Worker // Returns the thread type of a thread given its thread id. 380*6777b538SAndroid Build Coastguard Worker static std::optional<ThreadType> GetThreadTypeFromThreadId( 381*6777b538SAndroid Build Coastguard Worker ProcessId process_id, 382*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id); 383*6777b538SAndroid Build Coastguard Worker 384*6777b538SAndroid Build Coastguard Worker // Returns a SequenceChecker which should be used to verify that all 385*6777b538SAndroid Build Coastguard Worker // cross-process priority changes are performed without races. 386*6777b538SAndroid Build Coastguard Worker static SequenceCheckerImpl& GetCrossProcessThreadPrioritySequenceChecker(); 387*6777b538SAndroid Build Coastguard Worker 388*6777b538SAndroid Build Coastguard Worker protected: 389*6777b538SAndroid Build Coastguard Worker static void SetThreadTypeInternal(PlatformThreadId process_id, 390*6777b538SAndroid Build Coastguard Worker PlatformThreadId thread_id, 391*6777b538SAndroid Build Coastguard Worker ThreadType thread_type, 392*6777b538SAndroid Build Coastguard Worker IsViaIPC via_ipc); 393*6777b538SAndroid Build Coastguard Worker }; 394*6777b538SAndroid Build Coastguard Worker #endif // BUILDFLAG(IS_CHROMEOS) 395*6777b538SAndroid Build Coastguard Worker 396*6777b538SAndroid Build Coastguard Worker // Alias to the correct platform-specific class based on preprocessor directives 397*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE) 398*6777b538SAndroid Build Coastguard Worker using PlatformThread = PlatformThreadApple; 399*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_CHROMEOS) 400*6777b538SAndroid Build Coastguard Worker using PlatformThread = PlatformThreadChromeOS; 401*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_LINUX) 402*6777b538SAndroid Build Coastguard Worker using PlatformThread = PlatformThreadLinux; 403*6777b538SAndroid Build Coastguard Worker #else 404*6777b538SAndroid Build Coastguard Worker using PlatformThread = PlatformThreadBase; 405*6777b538SAndroid Build Coastguard Worker #endif 406*6777b538SAndroid Build Coastguard Worker 407*6777b538SAndroid Build Coastguard Worker namespace internal { 408*6777b538SAndroid Build Coastguard Worker 409*6777b538SAndroid Build Coastguard Worker void SetCurrentThreadType(ThreadType thread_type, 410*6777b538SAndroid Build Coastguard Worker MessagePumpType pump_type_hint); 411*6777b538SAndroid Build Coastguard Worker 412*6777b538SAndroid Build Coastguard Worker void SetCurrentThreadTypeImpl(ThreadType thread_type, 413*6777b538SAndroid Build Coastguard Worker MessagePumpType pump_type_hint); 414*6777b538SAndroid Build Coastguard Worker 415*6777b538SAndroid Build Coastguard Worker } // namespace internal 416*6777b538SAndroid Build Coastguard Worker 417*6777b538SAndroid Build Coastguard Worker } // namespace base 418*6777b538SAndroid Build Coastguard Worker 419*6777b538SAndroid Build Coastguard Worker #endif // BASE_THREADING_PLATFORM_THREAD_H_ 420