1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be
3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file.
4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// WARNING: You should *NOT* be using this class directly.  PlatformThread is
6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// the low-level platform-specific abstraction to the OS's threading interface.
7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// You should instead be using a message-loop driven Thread, see thread.h.
8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
9b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#ifndef BASE_THREADING_PLATFORM_THREAD_H_
10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#define BASE_THREADING_PLATFORM_THREAD_H_
11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
120d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stddef.h>
130d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko
14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/base_export.h"
150d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include "base/macros.h"
16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/time/time.h"
17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "build/build_config.h"
18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_WIN)
20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <windows.h>
21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#elif defined(OS_POSIX)
22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <pthread.h>
23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <unistd.h>
24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif
25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base {
27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Used for logging. Always an integer value.
29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_WIN)
30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattypedef DWORD PlatformThreadId;
31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#elif defined(OS_POSIX)
32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erattypedef pid_t PlatformThreadId;
33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif
34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Used for thread checking and debugging.
36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Meant to be as fast as possible.
37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// These are produced by PlatformThread::CurrentRef(), and used to later
38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// check if we are on the same thread or not by using ==. These are safe
39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// to copy between threads, but can't be copied to another process as they
40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// have no meaning there. Also, the internal identifier can be re-used
41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// after a thread dies, so a PlatformThreadRef cannot be reliably used
42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// to distinguish a new thread from an old, dead thread.
43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass PlatformThreadRef {
44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public:
45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_WIN)
46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  typedef DWORD RefType;
47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#elif defined(OS_POSIX)
48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  typedef pthread_t RefType;
49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif
50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  PlatformThreadRef()
51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      : id_(0) {
52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  explicit PlatformThreadRef(RefType id)
55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      : id_(id) {
56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool operator==(PlatformThreadRef other) const {
59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return id_ == other.id_;
60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool is_null() const {
63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return id_ == 0;
64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private:
66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  RefType id_;
67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat};
68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Used to operate on threads.
70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass PlatformThreadHandle {
71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public:
72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_WIN)
73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  typedef void* Handle;
74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#elif defined(OS_POSIX)
75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  typedef pthread_t Handle;
76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif
77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
780d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  PlatformThreadHandle() : handle_(0) {}
79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
800d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  explicit PlatformThreadHandle(Handle handle) : handle_(handle) {}
81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool is_equal(const PlatformThreadHandle& other) const {
83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return handle_ == other.handle_;
84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  bool is_null() const {
87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return !handle_;
88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Handle platform_handle() const {
91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    return handle_;
92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private:
95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  Handle handle_;
96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat};
97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst PlatformThreadId kInvalidThreadId(0);
99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
1000d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// Valid values for priority of Thread::Options and SimpleThread::Options, and
1010d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// SetCurrentThreadPriority(), listed in increasing order of importance.
10245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenkoenum class ThreadPriority : int {
103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Suitable for threads that shouldn't disrupt high priority work.
104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  BACKGROUND,
105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Default priority level.
106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  NORMAL,
107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Suitable for threads which generate data for the display (at ~60Hz).
108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  DISPLAY,
109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Suitable for low-latency, glitch-resistant audio.
110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  REALTIME_AUDIO,
111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat};
112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// A namespace for low-level thread functions.
114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratclass BASE_EXPORT PlatformThread {
115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat public:
116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Implement this interface to run code on a background thread.  Your
117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // ThreadMain method will be called on the newly created thread.
118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  class BASE_EXPORT Delegate {
119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat   public:
120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    virtual void ThreadMain() = 0;
121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat   protected:
123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    virtual ~Delegate() {}
124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  };
125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Gets the current thread id, which may be useful for logging purposes.
127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static PlatformThreadId CurrentId();
128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Gets the current thread reference, which can be used to check if
130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // we're on the right thread quickly.
131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static PlatformThreadRef CurrentRef();
132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Get the handle representing the current thread. On Windows, this is a
134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // pseudo handle constant which will always represent the thread using it and
135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // hence should not be shared with other threads nor be used to differentiate
136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // the current thread from another.
137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static PlatformThreadHandle CurrentHandle();
138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Yield the current thread so another thread can be scheduled.
140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static void YieldCurrentThread();
141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Sleeps for the specified duration.
143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static void Sleep(base::TimeDelta duration);
144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
1450c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  // Sets the thread name visible to debuggers/tools. This will try to
1460c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  // initialize the context for current thread unless it's a WorkerThread.
147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static void SetName(const std::string& name);
148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Gets the thread name, if previously set by SetName.
150b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static const char* GetName();
151b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
152b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Creates a new thread.  The |stack_size| parameter can be 0 to indicate
153b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // that the default stack size should be used.  Upon success,
154b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // |*thread_handle| will be assigned a handle to the newly created thread,
155b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // and |delegate|'s ThreadMain method will be executed on the newly created
156b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // thread.
157b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // NOTE: When you are done with the thread handle, you must call Join to
158b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // release system resources associated with the thread.  You must ensure that
159b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // the Delegate object outlives the thread.
1600d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static bool Create(size_t stack_size,
1610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                     Delegate* delegate,
1620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                     PlatformThreadHandle* thread_handle) {
1630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko    return CreateWithPriority(stack_size, delegate, thread_handle,
1640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko                              ThreadPriority::NORMAL);
1650d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  }
166b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
167b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // CreateWithPriority() does the same thing as Create() except the priority of
1680d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // the thread is set based on |priority|.
169b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static bool CreateWithPriority(size_t stack_size, Delegate* delegate,
170b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                 PlatformThreadHandle* thread_handle,
171b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                 ThreadPriority priority);
172b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
173b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // CreateNonJoinable() does the same thing as Create() except the thread
174b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // cannot be Join()'d.  Therefore, it also does not output a
175b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // PlatformThreadHandle.
176b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static bool CreateNonJoinable(size_t stack_size, Delegate* delegate);
177b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
178b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // Joins with a thread created via the Create function.  This function blocks
179b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // the caller until the designated thread exits.  This will invalidate
180b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  // |thread_handle|.
181b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  static void Join(PlatformThreadHandle thread_handle);
182b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
1830c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  // Detaches and releases the thread handle. The thread is no longer joinable
1840c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  // and |thread_handle| is invalidated after this call.
1850c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez  static void Detach(PlatformThreadHandle thread_handle);
1860c4f26a46430b8c503c65f5cae1d2b6876d53e30Luis Hector Chavez
1870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Toggles the current thread's priority at runtime. A thread may not be able
1880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // to raise its priority back up after lowering it if the process does not
18945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // have a proper permission, e.g. CAP_SYS_NICE on Linux. A thread may not be
19045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko  // able to lower its priority back down after raising it to REALTIME_AUDIO.
1910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // Since changing other threads' priority is not permitted in favor of
1920d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // security, this interface is restricted to change only the current thread
1930d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  // priority (https://crbug.com/399473).
1940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static void SetCurrentThreadPriority(ThreadPriority priority);
195b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
1960d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko  static ThreadPriority GetCurrentThreadPriority();
197b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
198b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat private:
199b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformThread);
200b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat};
201b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
202b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}  // namespace base
203b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
204b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif  // BASE_THREADING_PLATFORM_THREAD_H_
205