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

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: no priority bump 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 SetThreadPriority(GetDesiredThreadPriority());
45
42 // Get the sequence containing the next task to execute. 46 // Get the sequence containing the next task to execute.
43 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_); 47 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_);
44 if (!sequence) { 48 if (!sequence) {
45 if (outer_->delegate_->CanDetach(outer_)) { 49 if (outer_->delegate_->CanDetach(outer_)) {
46 detached_thread = outer_->Detach(); 50 detached_thread = outer_->Detach();
47 if (detached_thread) { 51 if (detached_thread) {
48 DCHECK_EQ(detached_thread.get(), this); 52 DCHECK_EQ(detached_thread.get(), this);
49 PlatformThread::Detach(thread_handle_); 53 PlatformThread::Detach(thread_handle_);
50 outer_ = nullptr; 54 outer_ = nullptr;
51 break; 55 break;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 88 }
85 89
86 void Join() { PlatformThread::Join(thread_handle_); } 90 void Join() { PlatformThread::Join(thread_handle_); }
87 91
88 void WakeUp() { wake_up_event_.Signal(); } 92 void WakeUp() { wake_up_event_.Signal(); }
89 93
90 bool IsWakeUpPending() { return wake_up_event_.IsSignaled(); } 94 bool IsWakeUpPending() { return wake_up_event_.IsSignaled(); }
91 95
92 private: 96 private:
93 Thread(SchedulerWorker* outer) 97 Thread(SchedulerWorker* outer)
94 : outer_(outer), 98 : outer_(outer),
95 wake_up_event_(WaitableEvent::ResetPolicy::MANUAL, 99 wake_up_event_(WaitableEvent::ResetPolicy::MANUAL,
96 WaitableEvent::InitialState::NOT_SIGNALED) { 100 WaitableEvent::InitialState::NOT_SIGNALED),
101 current_thread_priority_(GetDesiredThreadPriority()) {
97 DCHECK(outer_); 102 DCHECK(outer_);
98 } 103 }
99 104
100 void Initialize() { 105 void Initialize() {
101 constexpr size_t kDefaultStackSize = 0; 106 constexpr size_t kDefaultStackSize = 0;
102 PlatformThread::CreateWithPriority(kDefaultStackSize, this, 107 PlatformThread::CreateWithPriority(kDefaultStackSize, this, &thread_handle_,
103 &thread_handle_, 108 current_thread_priority_);
104 outer_->thread_priority_);
105 } 109 }
106 110
107 void WaitForWork() { 111 void WaitForWork() {
108 DCHECK(outer_); 112 DCHECK(outer_);
109 const TimeDelta sleep_time = outer_->delegate_->GetSleepTimeout(); 113 const TimeDelta sleep_time = outer_->delegate_->GetSleepTimeout();
110 if (sleep_time.is_max()) { 114 if (sleep_time.is_max()) {
111 // Calling TimedWait with TimeDelta::Max is not recommended per 115 // Calling TimedWait with TimeDelta::Max is not recommended per
112 // http://crbug.com/465948. 116 // http://crbug.com/465948.
113 wake_up_event_.Wait(); 117 wake_up_event_.Wait();
114 } else { 118 } else {
115 wake_up_event_.TimedWait(sleep_time); 119 wake_up_event_.TimedWait(sleep_time);
116 } 120 }
117 wake_up_event_.Reset(); 121 wake_up_event_.Reset();
118 } 122 }
119 123
124 // Returns the desired thread priority based on the worker priority and the
125 // current shutdown state.
126 ThreadPriority GetDesiredThreadPriority() {
127 DCHECK(outer_);
128
129 if (outer_->task_tracker_->HasShutdownStarted() &&
130 static_cast<int>(outer_->thread_priority_) <
131 static_cast<int>(ThreadPriority::NORMAL)) {
132 return ThreadPriority::NORMAL;
133 }
134 return outer_->thread_priority_;
135 }
136
137 void SetThreadPriority(ThreadPriority desired_thread_priority) {
138 if (desired_thread_priority == current_thread_priority_)
139 return;
140
141 #if defined(OS_LINUX)
142 if (static_cast<int>(desired_thread_priority) >
143 static_cast<int>(current_thread_priority_)) {
gab 2016/07/21 21:29:51 If we can't bring it up, we shouldn't bring it dow
fdoray 2016/07/22 12:56:32 Done. I disabled this method completely on Linux.
gab 2016/07/22 13:33:26 An alternate option is to detach the BACKGROUND th
144 // Increasing the thread priority requires the CAP_SYS_NICE capability on
145 // Linux.
146 return;
147 }
148 #endif // defined(OS_LINUX)
149
150 PlatformThread::SetCurrentThreadPriority(desired_thread_priority);
151 current_thread_priority_ = desired_thread_priority;
152 }
153
120 PlatformThreadHandle thread_handle_; 154 PlatformThreadHandle thread_handle_;
121 155
122 SchedulerWorker* outer_; 156 SchedulerWorker* outer_;
123 157
124 // Event signaled to wake up this thread. 158 // Event signaled to wake up this thread.
125 WaitableEvent wake_up_event_; 159 WaitableEvent wake_up_event_;
126 160
161 // Current priority of this thread. May be different from
162 // |outer_->thread_priority_| during shutdown.
163 ThreadPriority current_thread_priority_;
164
127 DISALLOW_COPY_AND_ASSIGN(Thread); 165 DISALLOW_COPY_AND_ASSIGN(Thread);
128 }; 166 };
129 167
130 std::unique_ptr<SchedulerWorker> SchedulerWorker::Create( 168 std::unique_ptr<SchedulerWorker> SchedulerWorker::Create(
131 ThreadPriority thread_priority, 169 ThreadPriority thread_priority,
132 std::unique_ptr<Delegate> delegate, 170 std::unique_ptr<Delegate> delegate,
133 TaskTracker* task_tracker, 171 TaskTracker* task_tracker,
134 InitialState initial_state) { 172 InitialState initial_state) {
135 std::unique_ptr<SchedulerWorker> worker( 173 std::unique_ptr<SchedulerWorker> worker(
136 new SchedulerWorker(thread_priority, std::move(delegate), task_tracker)); 174 new SchedulerWorker(thread_priority, std::move(delegate), task_tracker));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 CreateThread(); 251 CreateThread();
214 } 252 }
215 253
216 bool SchedulerWorker::ShouldExitForTesting() const { 254 bool SchedulerWorker::ShouldExitForTesting() const {
217 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); 255 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_);
218 return should_exit_for_testing_; 256 return should_exit_for_testing_;
219 } 257 }
220 258
221 } // namespace internal 259 } // namespace internal
222 } // namespace base 260 } // 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