Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(694)

Side by Side Diff: base/task_scheduler/scheduler_worker_thread.h

Issue 2044023003: Virtualize The Existence of a Scheduler Worker Thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@detach
Patch Set: CR Feedback Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_WORKER_THREAD_H_ 5 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_WORKER_THREAD_H_
6 #define BASE_TASK_SCHEDULER_SCHEDULER_WORKER_THREAD_H_ 6 #define BASE_TASK_SCHEDULER_SCHEDULER_WORKER_THREAD_H_
7 7
8 #include <memory> 8 #include <memory>
9 9
10 #include "base/base_export.h" 10 #include "base/base_export.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
13 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
14 #include "base/task_scheduler/scheduler_lock.h" 14 #include "base/task_scheduler/scheduler_lock.h"
15 #include "base/task_scheduler/sequence.h" 15 #include "base/task_scheduler/sequence.h"
16 #include "base/threading/platform_thread.h" 16 #include "base/threading/platform_thread.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 18
19 namespace base { 19 namespace base {
20
gab 2016/06/10 16:15:21 rm empty line
robliao 2016/06/10 18:03:41 Done.
20 namespace internal { 21 namespace internal {
21 22
22 class TaskTracker; 23 class TaskTracker;
23 24
24 // A thread that runs Tasks from Sequences returned by a delegate. 25 // A worker that manages at most one thread to run Tasks from Sequences returned
26 // by a delegate.
25 // 27 //
26 // A SchedulerWorkerThread starts out sleeping. It is woken up by a call to 28 // A SchedulerWorkerThread starts out sleeping. It is woken up by a call to
27 // WakeUp(). After a wake-up, a SchedulerWorkerThread runs Tasks from Sequences 29 // WakeUp(). After a wake-up, a SchedulerWorkerThread runs Tasks from Sequences
28 // returned by the GetWork() method of its delegate as long as it doesn't return 30 // returned by the GetWork() method of its delegate as long as it doesn't return
29 // nullptr. It also periodically checks with its TaskTracker whether shutdown 31 // nullptr. It also periodically checks with its TaskTracker whether shutdown
30 // has completed and exits when it has. 32 // has completed and exits when it has.
31 // 33 //
34 // The worker is free to release and reallocate thread suggestions with guidance
gab 2016/06/10 16:15:20 "thread suggestions"?
robliao 2016/06/10 18:03:41 Fixed!
35 // from the delegate
36 //
32 // This class is thread-safe. 37 // This class is thread-safe.
33 class BASE_EXPORT SchedulerWorkerThread : public PlatformThread::Delegate { 38 class BASE_EXPORT SchedulerWorkerThread {
34 public: 39 public:
35 // Delegate interface for SchedulerWorkerThread. The methods are always called 40 // Delegate interface for SchedulerWorkerThread. The methods are always called
36 // from the thread managed by the SchedulerWorkerThread instance. 41 // from the thread managed by the SchedulerWorkerThread instance.
37 class Delegate { 42 class Delegate {
38 public: 43 public:
39 virtual ~Delegate() = default; 44 virtual ~Delegate() = default;
40 45
41 // Called by |worker_thread| when it enters its main function. 46 // Called when |worker_thread|'s worker enters the main function.
47 // If a thread is recreated after detachment, this call will occur again.
42 virtual void OnMainEntry(SchedulerWorkerThread* worker_thread) = 0; 48 virtual void OnMainEntry(SchedulerWorkerThread* worker_thread) = 0;
43 49
44 // Called by |worker_thread| to get a Sequence from which to run a Task. 50 // Called by |worker_thread| to get a Sequence from which to run a Task.
45 virtual scoped_refptr<Sequence> GetWork( 51 virtual scoped_refptr<Sequence> GetWork(
46 SchedulerWorkerThread* worker_thread) = 0; 52 SchedulerWorkerThread* worker_thread) = 0;
47 53
48 // Called when |sequence| isn't empty after the SchedulerWorkerThread pops a 54 // Called when |sequence| isn't empty after the SchedulerWorkerThread pops a
49 // Task from it. |sequence| is the last Sequence returned by GetWork(). 55 // Task from it. |sequence| is the last Sequence returned by GetWork().
50 virtual void ReEnqueueSequence(scoped_refptr<Sequence> sequence) = 0; 56 virtual void ReEnqueueSequence(scoped_refptr<Sequence> sequence) = 0;
51 57
52 // Called by |worker_thread| to determine how long to sleep before the next 58 // Called by |worker_thread| to determine how long to sleep before the next
53 // call to GetWork(). GetWork() may be called before this timeout expires 59 // call to GetWork(). GetWork() may be called before this timeout expires
54 // if the thread's WakeUp() method is called. 60 // if the thread's WakeUp() method is called.
55 virtual TimeDelta GetSleepTimeout() = 0; 61 virtual TimeDelta GetSleepTimeout() = 0;
62
63 // Called by |worker_thread| to see if it is allowed to detach if the last
64 // call to GetWork() returned nullptr.
65 // A SchedulerWorkerThread is free to ignore the request to detach.
gab 2016/06/10 16:15:21 Which "request to detach"? Is a return true here a
robliao 2016/06/10 18:03:41 Clarified. Today, it is.
66 //
67 // It is the responsibility of the delegate to determine if detachment is
68 // safe. If |worker_thread| is responsible for thread-affine work,
69 // detachment is generally not safe.
70 //
71 // - Future tasks may run on a different PlatformThread after detachment.
gab 2016/06/10 16:15:21 I don't think this is worth mentioning (i.e. it's
robliao 2016/06/10 18:03:41 sgtm, since threads are indeed virtualized now.
72 // - The next WakeUp() could be more costly due to new thread creation.
73 // - The worker will free resources if it can.
74 virtual bool CanDetach(SchedulerWorkerThread* worker_thread) = 0;
56 }; 75 };
57 76
77 enum class InitialWorkerState { ALIVE, DETACHED };
gab 2016/06/10 16:15:21 "InitialState" is good enough IMO, "Worker" is red
robliao 2016/06/10 18:03:42 sgtm. Done.
78
58 // Creates a SchedulerWorkerThread with priority |thread_priority| that runs 79 // Creates a SchedulerWorkerThread with priority |thread_priority| that runs
59 // Tasks from Sequences returned by |delegate|. |task_tracker| is used to 80 // Tasks from Sequences returned by |delegate|. |task_tracker| is used to
60 // handle shutdown behavior of Tasks. Returns nullptr if creating the 81 // handle shutdown behavior of Tasks. If |worker_state| is DETACHED, the
gab 2016/06/10 16:15:21 Is the idea that we would create |max_threads| SWT
robliao 2016/06/10 18:03:41 Yup. The new CL I have only creates one in ALIVE m
61 // underlying platform thread fails. 82 // worker will be created upon a WakeUp. Returns nullptr if creating the
83 // underlying platform thread fails during Create..
gab 2016/06/10 16:15:21 s/.././
robliao 2016/06/10 18:03:41 Done.
62 static std::unique_ptr<SchedulerWorkerThread> Create( 84 static std::unique_ptr<SchedulerWorkerThread> Create(
63 ThreadPriority thread_priority, 85 ThreadPriority thread_priority,
64 std::unique_ptr<Delegate> delegate, 86 std::unique_ptr<Delegate> delegate,
65 TaskTracker* task_tracker); 87 TaskTracker* task_tracker,
88 InitialWorkerState worker_state);
66 89
67 // Destroying a SchedulerWorkerThread in production is not allowed; it is 90 // Destroying a SchedulerWorkerThread in production is not allowed; it is
68 // always leaked. In tests, it can only be destroyed after JoinForTesting() 91 // always leaked. In tests, it can only be destroyed after JoinForTesting()
69 // has returned. 92 // has returned.
70 ~SchedulerWorkerThread() override; 93 ~SchedulerWorkerThread();
71 94
72 // Wakes up this SchedulerWorkerThread if it wasn't already awake. After this 95 // Wakes up this SchedulerWorkerThread if it wasn't already awake. After this
73 // is called, this SchedulerWorkerThread will run Tasks from Sequences 96 // is called, this SchedulerWorkerThread will run Tasks from Sequences
74 // returned by the GetWork() method of its delegate until it returns nullptr. 97 // returned by the GetWork() method of its delegate until it returns nullptr.
98 // May fail if the worker is detached.
gab 2016/06/10 16:15:21 Document what failure means since this is a void r
robliao 2016/06/10 18:03:41 Done.
75 void WakeUp(); 99 void WakeUp();
76 100
77 SchedulerWorkerThread::Delegate* delegate() { return delegate_.get(); } 101 SchedulerWorkerThread::Delegate* delegate() { return delegate_.get(); }
78 102
79 // Joins this SchedulerWorkerThread. If a Task is already running, it will be 103 // Joins this SchedulerWorkerThread. If a Task is already running, it will be
80 // allowed to complete its execution. This can only be called once. 104 // allowed to complete its execution. This can only be called once.
81 void JoinForTesting(); 105 void JoinForTesting();
gab 2016/06/10 16:15:21 Document that Detach() must always return false wh
robliao 2016/06/10 18:03:42 Doc'ed in Delegate::CanDetach().
82 106
107 // Returns ture if the worker is alive.
108 bool WorkerAliveForTesting() const;
109
83 private: 110 private:
111 class Worker;
112
84 SchedulerWorkerThread(ThreadPriority thread_priority, 113 SchedulerWorkerThread(ThreadPriority thread_priority,
85 std::unique_ptr<Delegate> delegate, 114 std::unique_ptr<Delegate> delegate,
86 TaskTracker* task_tracker); 115 TaskTracker* task_tracker);
87 116
88 // PlatformThread::Delegate: 117 // Returns the worker for ownership by the worker thread if the detach was
gab 2016/06/10 16:15:21 "for ownership by" => I don't understand this sent
robliao 2016/06/10 18:03:41 Clarified.
89 void ThreadMain() override; 118 // successful. If the detach is not possible, returns nullptr.
119 std::unique_ptr<SchedulerWorkerThread::Worker> Detach();
120
121 void CreateWorker();
122
123 void CreateWorkerAssertSynchronized();
90 124
91 bool ShouldExitForTesting() const; 125 bool ShouldExitForTesting() const;
92 126
93 // Platform thread managed by this SchedulerWorkerThread. 127 // Synchronizes access to |worker_|
94 PlatformThreadHandle thread_handle_; 128 mutable SchedulerLock worker_lock_;
95 129
96 // Event signaled to wake up this SchedulerWorkerThread. 130 // The underlying thread for this SchedulerWorkerThread.
97 WaitableEvent wake_up_event_; 131 std::unique_ptr<Worker> worker_;
98 132
133 const ThreadPriority thread_priority_;
99 const std::unique_ptr<Delegate> delegate_; 134 const std::unique_ptr<Delegate> delegate_;
100 TaskTracker* const task_tracker_; 135 TaskTracker* const task_tracker_;
101 136
102 // Synchronizes access to |should_exit_for_testing_|. 137 // Synchronizes access to |should_exit_for_testing_|.
103 mutable SchedulerLock should_exit_for_testing_lock_; 138 mutable SchedulerLock should_exit_for_testing_lock_;
104 139
105 // True once JoinForTesting() has been called. 140 // True once JoinForTesting() has been called.
106 bool should_exit_for_testing_ = false; 141 bool should_exit_for_testing_ = false;
107 142
108 DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerThread); 143 DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerThread);
109 }; 144 };
110 145
111 } // namespace internal 146 } // namespace internal
112 } // namespace base 147 } // namespace base
113 148
114 #endif // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_THREAD_H_ 149 #endif // BASE_TASK_SCHEDULER_SCHEDULER_WORKER_THREAD_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698