1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker // WARNING: You should *NOT* be using this class directly. PlatformThread is 6*635a8641SAndroid Build Coastguard Worker // the low-level platform-specific abstraction to the OS's threading interface. 7*635a8641SAndroid Build Coastguard Worker // You should instead be using a message-loop driven Thread, see thread.h. 8*635a8641SAndroid Build Coastguard Worker 9*635a8641SAndroid Build Coastguard Worker #ifndef BASE_THREADING_PLATFORM_THREAD_H_ 10*635a8641SAndroid Build Coastguard Worker #define BASE_THREADING_PLATFORM_THREAD_H_ 11*635a8641SAndroid Build Coastguard Worker 12*635a8641SAndroid Build Coastguard Worker #include <stddef.h> 13*635a8641SAndroid Build Coastguard Worker 14*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 15*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 16*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h" 17*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h" 18*635a8641SAndroid Build Coastguard Worker 19*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 20*635a8641SAndroid Build Coastguard Worker #include "base/win/windows_types.h" 21*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA) 22*635a8641SAndroid Build Coastguard Worker #include <zircon/types.h> 23*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) 24*635a8641SAndroid Build Coastguard Worker #include <mach/mach_types.h> 25*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) 26*635a8641SAndroid Build Coastguard Worker #include <pthread.h> 27*635a8641SAndroid Build Coastguard Worker #include <unistd.h> 28*635a8641SAndroid Build Coastguard Worker #endif 29*635a8641SAndroid Build Coastguard Worker 30*635a8641SAndroid Build Coastguard Worker namespace base { 31*635a8641SAndroid Build Coastguard Worker 32*635a8641SAndroid Build Coastguard Worker // Used for logging. Always an integer value. 33*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 34*635a8641SAndroid Build Coastguard Worker typedef DWORD PlatformThreadId; 35*635a8641SAndroid Build Coastguard Worker #elif defined(OS_FUCHSIA) 36*635a8641SAndroid Build Coastguard Worker typedef zx_handle_t PlatformThreadId; 37*635a8641SAndroid Build Coastguard Worker #elif defined(OS_MACOSX) 38*635a8641SAndroid Build Coastguard Worker typedef mach_port_t PlatformThreadId; 39*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) 40*635a8641SAndroid Build Coastguard Worker typedef pid_t PlatformThreadId; 41*635a8641SAndroid Build Coastguard Worker #endif 42*635a8641SAndroid Build Coastguard Worker 43*635a8641SAndroid Build Coastguard Worker // Used for thread checking and debugging. 44*635a8641SAndroid Build Coastguard Worker // Meant to be as fast as possible. 45*635a8641SAndroid Build Coastguard Worker // These are produced by PlatformThread::CurrentRef(), and used to later 46*635a8641SAndroid Build Coastguard Worker // check if we are on the same thread or not by using ==. These are safe 47*635a8641SAndroid Build Coastguard Worker // to copy between threads, but can't be copied to another process as they 48*635a8641SAndroid Build Coastguard Worker // have no meaning there. Also, the internal identifier can be re-used 49*635a8641SAndroid Build Coastguard Worker // after a thread dies, so a PlatformThreadRef cannot be reliably used 50*635a8641SAndroid Build Coastguard Worker // to distinguish a new thread from an old, dead thread. 51*635a8641SAndroid Build Coastguard Worker class PlatformThreadRef { 52*635a8641SAndroid Build Coastguard Worker public: 53*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 54*635a8641SAndroid Build Coastguard Worker typedef DWORD RefType; 55*635a8641SAndroid Build Coastguard Worker #else // OS_POSIX 56*635a8641SAndroid Build Coastguard Worker typedef pthread_t RefType; 57*635a8641SAndroid Build Coastguard Worker #endif PlatformThreadRef()58*635a8641SAndroid Build Coastguard Worker constexpr PlatformThreadRef() : id_(0) {} 59*635a8641SAndroid Build Coastguard Worker PlatformThreadRef(RefType id)60*635a8641SAndroid Build Coastguard Worker explicit constexpr PlatformThreadRef(RefType id) : id_(id) {} 61*635a8641SAndroid Build Coastguard Worker 62*635a8641SAndroid Build Coastguard Worker bool operator==(PlatformThreadRef other) const { 63*635a8641SAndroid Build Coastguard Worker return id_ == other.id_; 64*635a8641SAndroid Build Coastguard Worker } 65*635a8641SAndroid Build Coastguard Worker 66*635a8641SAndroid Build Coastguard Worker bool operator!=(PlatformThreadRef other) const { return id_ != other.id_; } 67*635a8641SAndroid Build Coastguard Worker is_null()68*635a8641SAndroid Build Coastguard Worker bool is_null() const { 69*635a8641SAndroid Build Coastguard Worker return id_ == 0; 70*635a8641SAndroid Build Coastguard Worker } 71*635a8641SAndroid Build Coastguard Worker private: 72*635a8641SAndroid Build Coastguard Worker RefType id_; 73*635a8641SAndroid Build Coastguard Worker }; 74*635a8641SAndroid Build Coastguard Worker 75*635a8641SAndroid Build Coastguard Worker // Used to operate on threads. 76*635a8641SAndroid Build Coastguard Worker class PlatformThreadHandle { 77*635a8641SAndroid Build Coastguard Worker public: 78*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN) 79*635a8641SAndroid Build Coastguard Worker typedef void* Handle; 80*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA) 81*635a8641SAndroid Build Coastguard Worker typedef pthread_t Handle; 82*635a8641SAndroid Build Coastguard Worker #endif 83*635a8641SAndroid Build Coastguard Worker PlatformThreadHandle()84*635a8641SAndroid Build Coastguard Worker constexpr PlatformThreadHandle() : handle_(0) {} 85*635a8641SAndroid Build Coastguard Worker PlatformThreadHandle(Handle handle)86*635a8641SAndroid Build Coastguard Worker explicit constexpr PlatformThreadHandle(Handle handle) : handle_(handle) {} 87*635a8641SAndroid Build Coastguard Worker is_equal(const PlatformThreadHandle & other)88*635a8641SAndroid Build Coastguard Worker bool is_equal(const PlatformThreadHandle& other) const { 89*635a8641SAndroid Build Coastguard Worker return handle_ == other.handle_; 90*635a8641SAndroid Build Coastguard Worker } 91*635a8641SAndroid Build Coastguard Worker is_null()92*635a8641SAndroid Build Coastguard Worker bool is_null() const { 93*635a8641SAndroid Build Coastguard Worker return !handle_; 94*635a8641SAndroid Build Coastguard Worker } 95*635a8641SAndroid Build Coastguard Worker platform_handle()96*635a8641SAndroid Build Coastguard Worker Handle platform_handle() const { 97*635a8641SAndroid Build Coastguard Worker return handle_; 98*635a8641SAndroid Build Coastguard Worker } 99*635a8641SAndroid Build Coastguard Worker 100*635a8641SAndroid Build Coastguard Worker private: 101*635a8641SAndroid Build Coastguard Worker Handle handle_; 102*635a8641SAndroid Build Coastguard Worker }; 103*635a8641SAndroid Build Coastguard Worker 104*635a8641SAndroid Build Coastguard Worker const PlatformThreadId kInvalidThreadId(0); 105*635a8641SAndroid Build Coastguard Worker 106*635a8641SAndroid Build Coastguard Worker // Valid values for priority of Thread::Options and SimpleThread::Options, and 107*635a8641SAndroid Build Coastguard Worker // SetCurrentThreadPriority(), listed in increasing order of importance. 108*635a8641SAndroid Build Coastguard Worker enum class ThreadPriority : int { 109*635a8641SAndroid Build Coastguard Worker // Suitable for threads that shouldn't disrupt high priority work. 110*635a8641SAndroid Build Coastguard Worker BACKGROUND, 111*635a8641SAndroid Build Coastguard Worker // Default priority level. 112*635a8641SAndroid Build Coastguard Worker NORMAL, 113*635a8641SAndroid Build Coastguard Worker // Suitable for threads which generate data for the display (at ~60Hz). 114*635a8641SAndroid Build Coastguard Worker DISPLAY, 115*635a8641SAndroid Build Coastguard Worker // Suitable for low-latency, glitch-resistant audio. 116*635a8641SAndroid Build Coastguard Worker REALTIME_AUDIO, 117*635a8641SAndroid Build Coastguard Worker }; 118*635a8641SAndroid Build Coastguard Worker 119*635a8641SAndroid Build Coastguard Worker // A namespace for low-level thread functions. 120*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT PlatformThread { 121*635a8641SAndroid Build Coastguard Worker public: 122*635a8641SAndroid Build Coastguard Worker // Implement this interface to run code on a background thread. Your 123*635a8641SAndroid Build Coastguard Worker // ThreadMain method will be called on the newly created thread. 124*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT Delegate { 125*635a8641SAndroid Build Coastguard Worker public: 126*635a8641SAndroid Build Coastguard Worker virtual void ThreadMain() = 0; 127*635a8641SAndroid Build Coastguard Worker 128*635a8641SAndroid Build Coastguard Worker protected: 129*635a8641SAndroid Build Coastguard Worker virtual ~Delegate() = default; 130*635a8641SAndroid Build Coastguard Worker }; 131*635a8641SAndroid Build Coastguard Worker 132*635a8641SAndroid Build Coastguard Worker // Gets the current thread id, which may be useful for logging purposes. 133*635a8641SAndroid Build Coastguard Worker static PlatformThreadId CurrentId(); 134*635a8641SAndroid Build Coastguard Worker 135*635a8641SAndroid Build Coastguard Worker // Gets the current thread reference, which can be used to check if 136*635a8641SAndroid Build Coastguard Worker // we're on the right thread quickly. 137*635a8641SAndroid Build Coastguard Worker static PlatformThreadRef CurrentRef(); 138*635a8641SAndroid Build Coastguard Worker 139*635a8641SAndroid Build Coastguard Worker // Get the handle representing the current thread. On Windows, this is a 140*635a8641SAndroid Build Coastguard Worker // pseudo handle constant which will always represent the thread using it and 141*635a8641SAndroid Build Coastguard Worker // hence should not be shared with other threads nor be used to differentiate 142*635a8641SAndroid Build Coastguard Worker // the current thread from another. 143*635a8641SAndroid Build Coastguard Worker static PlatformThreadHandle CurrentHandle(); 144*635a8641SAndroid Build Coastguard Worker 145*635a8641SAndroid Build Coastguard Worker // Yield the current thread so another thread can be scheduled. 146*635a8641SAndroid Build Coastguard Worker static void YieldCurrentThread(); 147*635a8641SAndroid Build Coastguard Worker 148*635a8641SAndroid Build Coastguard Worker // Sleeps for the specified duration. 149*635a8641SAndroid Build Coastguard Worker static void Sleep(base::TimeDelta duration); 150*635a8641SAndroid Build Coastguard Worker 151*635a8641SAndroid Build Coastguard Worker // Sets the thread name visible to debuggers/tools. This will try to 152*635a8641SAndroid Build Coastguard Worker // initialize the context for current thread unless it's a WorkerThread. 153*635a8641SAndroid Build Coastguard Worker static void SetName(const std::string& name); 154*635a8641SAndroid Build Coastguard Worker 155*635a8641SAndroid Build Coastguard Worker // Gets the thread name, if previously set by SetName. 156*635a8641SAndroid Build Coastguard Worker static const char* GetName(); 157*635a8641SAndroid Build Coastguard Worker 158*635a8641SAndroid Build Coastguard Worker // Creates a new thread. The |stack_size| parameter can be 0 to indicate 159*635a8641SAndroid Build Coastguard Worker // that the default stack size should be used. Upon success, 160*635a8641SAndroid Build Coastguard Worker // |*thread_handle| will be assigned a handle to the newly created thread, 161*635a8641SAndroid Build Coastguard Worker // and |delegate|'s ThreadMain method will be executed on the newly created 162*635a8641SAndroid Build Coastguard Worker // thread. 163*635a8641SAndroid Build Coastguard Worker // NOTE: When you are done with the thread handle, you must call Join to 164*635a8641SAndroid Build Coastguard Worker // release system resources associated with the thread. You must ensure that 165*635a8641SAndroid Build Coastguard Worker // the Delegate object outlives the thread. Create(size_t stack_size,Delegate * delegate,PlatformThreadHandle * thread_handle)166*635a8641SAndroid Build Coastguard Worker static bool Create(size_t stack_size, 167*635a8641SAndroid Build Coastguard Worker Delegate* delegate, 168*635a8641SAndroid Build Coastguard Worker PlatformThreadHandle* thread_handle) { 169*635a8641SAndroid Build Coastguard Worker return CreateWithPriority(stack_size, delegate, thread_handle, 170*635a8641SAndroid Build Coastguard Worker ThreadPriority::NORMAL); 171*635a8641SAndroid Build Coastguard Worker } 172*635a8641SAndroid Build Coastguard Worker 173*635a8641SAndroid Build Coastguard Worker // CreateWithPriority() does the same thing as Create() except the priority of 174*635a8641SAndroid Build Coastguard Worker // the thread is set based on |priority|. 175*635a8641SAndroid Build Coastguard Worker static bool CreateWithPriority(size_t stack_size, Delegate* delegate, 176*635a8641SAndroid Build Coastguard Worker PlatformThreadHandle* thread_handle, 177*635a8641SAndroid Build Coastguard Worker ThreadPriority priority); 178*635a8641SAndroid Build Coastguard Worker 179*635a8641SAndroid Build Coastguard Worker // CreateNonJoinable() does the same thing as Create() except the thread 180*635a8641SAndroid Build Coastguard Worker // cannot be Join()'d. Therefore, it also does not output a 181*635a8641SAndroid Build Coastguard Worker // PlatformThreadHandle. 182*635a8641SAndroid Build Coastguard Worker static bool CreateNonJoinable(size_t stack_size, Delegate* delegate); 183*635a8641SAndroid Build Coastguard Worker 184*635a8641SAndroid Build Coastguard Worker // CreateNonJoinableWithPriority() does the same thing as CreateNonJoinable() 185*635a8641SAndroid Build Coastguard Worker // except the priority of the thread is set based on |priority|. 186*635a8641SAndroid Build Coastguard Worker static bool CreateNonJoinableWithPriority(size_t stack_size, 187*635a8641SAndroid Build Coastguard Worker Delegate* delegate, 188*635a8641SAndroid Build Coastguard Worker ThreadPriority priority); 189*635a8641SAndroid Build Coastguard Worker 190*635a8641SAndroid Build Coastguard Worker // Joins with a thread created via the Create function. This function blocks 191*635a8641SAndroid Build Coastguard Worker // the caller until the designated thread exits. This will invalidate 192*635a8641SAndroid Build Coastguard Worker // |thread_handle|. 193*635a8641SAndroid Build Coastguard Worker static void Join(PlatformThreadHandle thread_handle); 194*635a8641SAndroid Build Coastguard Worker 195*635a8641SAndroid Build Coastguard Worker // Detaches and releases the thread handle. The thread is no longer joinable 196*635a8641SAndroid Build Coastguard Worker // and |thread_handle| is invalidated after this call. 197*635a8641SAndroid Build Coastguard Worker static void Detach(PlatformThreadHandle thread_handle); 198*635a8641SAndroid Build Coastguard Worker 199*635a8641SAndroid Build Coastguard Worker // Returns true if SetCurrentThreadPriority() can be used to increase the 200*635a8641SAndroid Build Coastguard Worker // priority of the current thread. 201*635a8641SAndroid Build Coastguard Worker static bool CanIncreaseCurrentThreadPriority(); 202*635a8641SAndroid Build Coastguard Worker 203*635a8641SAndroid Build Coastguard Worker // Toggles the current thread's priority at runtime. 204*635a8641SAndroid Build Coastguard Worker // 205*635a8641SAndroid Build Coastguard Worker // A thread may not be able to raise its priority back up after lowering it if 206*635a8641SAndroid Build Coastguard Worker // the process does not have a proper permission, e.g. CAP_SYS_NICE on Linux. 207*635a8641SAndroid Build Coastguard Worker // A thread may not be able to lower its priority back down after raising it 208*635a8641SAndroid Build Coastguard Worker // to REALTIME_AUDIO. 209*635a8641SAndroid Build Coastguard Worker // 210*635a8641SAndroid Build Coastguard Worker // This function must not be called from the main thread on Mac. This is to 211*635a8641SAndroid Build Coastguard Worker // avoid performance regressions (https://crbug.com/601270). 212*635a8641SAndroid Build Coastguard Worker // 213*635a8641SAndroid Build Coastguard Worker // Since changing other threads' priority is not permitted in favor of 214*635a8641SAndroid Build Coastguard Worker // security, this interface is restricted to change only the current thread 215*635a8641SAndroid Build Coastguard Worker // priority (https://crbug.com/399473). 216*635a8641SAndroid Build Coastguard Worker static void SetCurrentThreadPriority(ThreadPriority priority); 217*635a8641SAndroid Build Coastguard Worker 218*635a8641SAndroid Build Coastguard Worker static ThreadPriority GetCurrentThreadPriority(); 219*635a8641SAndroid Build Coastguard Worker 220*635a8641SAndroid Build Coastguard Worker #if defined(OS_LINUX) 221*635a8641SAndroid Build Coastguard Worker // Toggles a specific thread's priority at runtime. This can be used to 222*635a8641SAndroid Build Coastguard Worker // change the priority of a thread in a different process and will fail 223*635a8641SAndroid Build Coastguard Worker // if the calling process does not have proper permissions. The 224*635a8641SAndroid Build Coastguard Worker // SetCurrentThreadPriority() function above is preferred in favor of 225*635a8641SAndroid Build Coastguard Worker // security but on platforms where sandboxed processes are not allowed to 226*635a8641SAndroid Build Coastguard Worker // change priority this function exists to allow a non-sandboxed process 227*635a8641SAndroid Build Coastguard Worker // to change the priority of sandboxed threads for improved performance. 228*635a8641SAndroid Build Coastguard Worker // Warning: Don't use this for a main thread because that will change the 229*635a8641SAndroid Build Coastguard Worker // whole thread group's (i.e. process) priority. 230*635a8641SAndroid Build Coastguard Worker static void SetThreadPriority(PlatformThreadId thread_id, 231*635a8641SAndroid Build Coastguard Worker ThreadPriority priority); 232*635a8641SAndroid Build Coastguard Worker #endif 233*635a8641SAndroid Build Coastguard Worker 234*635a8641SAndroid Build Coastguard Worker private: 235*635a8641SAndroid Build Coastguard Worker DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformThread); 236*635a8641SAndroid Build Coastguard Worker }; 237*635a8641SAndroid Build Coastguard Worker 238*635a8641SAndroid Build Coastguard Worker } // namespace base 239*635a8641SAndroid Build Coastguard Worker 240*635a8641SAndroid Build Coastguard Worker #endif // BASE_THREADING_PLATFORM_THREAD_H_ 241