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

Side by Side Diff: base/task_scheduler/scheduler_worker.cc

Issue 2161213002: TaskScheduler: Bump thread priority during shutdown. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: CR gab #26 (Set* -> Update* and disable on Linux) Created 4 years, 5 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
« no previous file with comments | « no previous file | base/task_scheduler/scheduler_worker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "base/task_scheduler/scheduler_worker.h" 5 #include "base/task_scheduler/scheduler_worker.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/task_scheduler/task_tracker.h" 12 #include "base/task_scheduler/task_tracker.h"
13 #include "build/build_config.h"
13 14
14 namespace base { 15 namespace base {
15 namespace internal { 16 namespace internal {
16 17
17 class SchedulerWorker::Thread : public PlatformThread::Delegate { 18 class SchedulerWorker::Thread : public PlatformThread::Delegate {
18 public: 19 public:
19 ~Thread() override = default; 20 ~Thread() override = default;
20 21
21 static std::unique_ptr<Thread> Create(SchedulerWorker* outer) { 22 static std::unique_ptr<Thread> Create(SchedulerWorker* outer) {
22 std::unique_ptr<Thread> thread(new Thread(outer)); 23 std::unique_ptr<Thread> thread(new Thread(outer));
23 thread->Initialize(); 24 thread->Initialize();
24 if (thread->thread_handle_.is_null()) 25 if (thread->thread_handle_.is_null())
25 return nullptr; 26 return nullptr;
26 return thread; 27 return thread;
27 } 28 }
28 29
29 // PlatformThread::Delegate. 30 // PlatformThread::Delegate.
30 void ThreadMain() override { 31 void ThreadMain() override {
31 // Set if this thread was detached. 32 // Set if this thread was detached.
32 std::unique_ptr<Thread> detached_thread; 33 std::unique_ptr<Thread> detached_thread;
33 34
34 outer_->delegate_->OnMainEntry(outer_); 35 outer_->delegate_->OnMainEntry(outer_);
35 36
36 // A SchedulerWorker starts out waiting for work. 37 // A SchedulerWorker starts out waiting for work.
37 WaitForWork(); 38 WaitForWork();
38 39
39 while (!outer_->task_tracker_->IsShutdownComplete() && 40 while (!outer_->task_tracker_->IsShutdownComplete() &&
40 !outer_->ShouldExitForTesting()) { 41 !outer_->ShouldExitForTesting()) {
41 DCHECK(outer_); 42 DCHECK(outer_);
43
44 #if !defined(OS_LINUX)
45 UpdateThreadPriority(GetDesiredThreadPriority());
46 #endif
47
42 // Get the sequence containing the next task to execute. 48 // Get the sequence containing the next task to execute.
43 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_); 49 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_);
44 if (!sequence) { 50 if (!sequence) {
45 if (outer_->delegate_->CanDetach(outer_)) { 51 if (outer_->delegate_->CanDetach(outer_)) {
46 detached_thread = outer_->Detach(); 52 detached_thread = outer_->Detach();
47 if (detached_thread) { 53 if (detached_thread) {
48 DCHECK_EQ(detached_thread.get(), this); 54 DCHECK_EQ(detached_thread.get(), this);
49 PlatformThread::Detach(thread_handle_); 55 PlatformThread::Detach(thread_handle_);
50 outer_ = nullptr; 56 outer_ = nullptr;
51 break; 57 break;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 90 }
85 91
86 void Join() { PlatformThread::Join(thread_handle_); } 92 void Join() { PlatformThread::Join(thread_handle_); }
87 93
88 void WakeUp() { wake_up_event_.Signal(); } 94 void WakeUp() { wake_up_event_.Signal(); }
89 95
90 bool IsWakeUpPending() { return wake_up_event_.IsSignaled(); } 96 bool IsWakeUpPending() { return wake_up_event_.IsSignaled(); }
91 97
92 private: 98 private:
93 Thread(SchedulerWorker* outer) 99 Thread(SchedulerWorker* outer)
94 : outer_(outer), 100 : outer_(outer),
95 wake_up_event_(WaitableEvent::ResetPolicy::MANUAL, 101 wake_up_event_(WaitableEvent::ResetPolicy::MANUAL,
96 WaitableEvent::InitialState::NOT_SIGNALED) { 102 WaitableEvent::InitialState::NOT_SIGNALED),
103 current_thread_priority_(GetDesiredThreadPriority()) {
97 DCHECK(outer_); 104 DCHECK(outer_);
98 } 105 }
99 106
100 void Initialize() { 107 void Initialize() {
101 constexpr size_t kDefaultStackSize = 0; 108 constexpr size_t kDefaultStackSize = 0;
102 PlatformThread::CreateWithPriority(kDefaultStackSize, this, 109 PlatformThread::CreateWithPriority(kDefaultStackSize, this, &thread_handle_,
103 &thread_handle_, 110 current_thread_priority_);
104 outer_->thread_priority_);
105 } 111 }
106 112
107 void WaitForWork() { 113 void WaitForWork() {
108 DCHECK(outer_); 114 DCHECK(outer_);
109 const TimeDelta sleep_time = outer_->delegate_->GetSleepTimeout(); 115 const TimeDelta sleep_time = outer_->delegate_->GetSleepTimeout();
110 if (sleep_time.is_max()) { 116 if (sleep_time.is_max()) {
111 // Calling TimedWait with TimeDelta::Max is not recommended per 117 // Calling TimedWait with TimeDelta::Max is not recommended per
112 // http://crbug.com/465948. 118 // http://crbug.com/465948.
113 wake_up_event_.Wait(); 119 wake_up_event_.Wait();
114 } else { 120 } else {
115 wake_up_event_.TimedWait(sleep_time); 121 wake_up_event_.TimedWait(sleep_time);
116 } 122 }
117 wake_up_event_.Reset(); 123 wake_up_event_.Reset();
118 } 124 }
119 125
126 // Returns the desired thread priority based on the worker priority and the
127 // current shutdown state.
128 ThreadPriority GetDesiredThreadPriority() {
129 DCHECK(outer_);
130
131 if (outer_->task_tracker_->HasShutdownStarted() &&
132 static_cast<int>(outer_->thread_priority_) <
133 static_cast<int>(ThreadPriority::NORMAL)) {
134 return ThreadPriority::NORMAL;
135 }
136 return outer_->thread_priority_;
137 }
138
139 // Increasing the thread priority requires the CAP_SYS_NICE capability on
140 // Linux.
141 #if !defined(OS_LINUX)
142 void UpdateThreadPriority(ThreadPriority desired_thread_priority) {
143 if (desired_thread_priority == current_thread_priority_)
144 return;
145
146 PlatformThread::SetCurrentThreadPriority(desired_thread_priority);
147 current_thread_priority_ = desired_thread_priority;
148 }
149 #endif // !defined(OS_LINUX)
150
120 PlatformThreadHandle thread_handle_; 151 PlatformThreadHandle thread_handle_;
121 152
122 SchedulerWorker* outer_; 153 SchedulerWorker* outer_;
123 154
124 // Event signaled to wake up this thread. 155 // Event signaled to wake up this thread.
125 WaitableEvent wake_up_event_; 156 WaitableEvent wake_up_event_;
126 157
158 // Current priority of this thread. May be different from
159 // |outer_->thread_priority_| during shutdown.
160 ThreadPriority current_thread_priority_;
161
127 DISALLOW_COPY_AND_ASSIGN(Thread); 162 DISALLOW_COPY_AND_ASSIGN(Thread);
128 }; 163 };
129 164
130 std::unique_ptr<SchedulerWorker> SchedulerWorker::Create( 165 std::unique_ptr<SchedulerWorker> SchedulerWorker::Create(
131 ThreadPriority thread_priority, 166 ThreadPriority thread_priority,
132 std::unique_ptr<Delegate> delegate, 167 std::unique_ptr<Delegate> delegate,
133 TaskTracker* task_tracker, 168 TaskTracker* task_tracker,
134 InitialState initial_state) { 169 InitialState initial_state) {
135 std::unique_ptr<SchedulerWorker> worker( 170 std::unique_ptr<SchedulerWorker> worker(
136 new SchedulerWorker(thread_priority, std::move(delegate), task_tracker)); 171 new SchedulerWorker(thread_priority, std::move(delegate), task_tracker));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 CreateThread(); 248 CreateThread();
214 } 249 }
215 250
216 bool SchedulerWorker::ShouldExitForTesting() const { 251 bool SchedulerWorker::ShouldExitForTesting() const {
217 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); 252 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_);
218 return should_exit_for_testing_; 253 return should_exit_for_testing_;
219 } 254 }
220 255
221 } // namespace internal 256 } // namespace internal
222 } // namespace base 257 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | base/task_scheduler/scheduler_worker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698