xref: /aosp_15_r20/external/cronet/base/threading/platform_thread.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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