platform_thread.h 9.3 KB

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