Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 WaitForWork(); | 42 WaitForWork(); |
| 43 | 43 |
| 44 while (!outer_->task_tracker_->IsShutdownComplete() && | 44 while (!outer_->task_tracker_->IsShutdownComplete() && |
| 45 !outer_->ShouldExitForTesting()) { | 45 !outer_->ShouldExitForTesting()) { |
| 46 DCHECK(outer_); | 46 DCHECK(outer_); |
| 47 | 47 |
| 48 #if defined(OS_MACOSX) | 48 #if defined(OS_MACOSX) |
| 49 mac::ScopedNSAutoreleasePool autorelease_pool; | 49 mac::ScopedNSAutoreleasePool autorelease_pool; |
| 50 #endif | 50 #endif |
| 51 | 51 |
| 52 #if !defined(OS_LINUX) | |
| 53 UpdateThreadPriority(GetDesiredThreadPriority()); | 52 UpdateThreadPriority(GetDesiredThreadPriority()); |
| 54 #endif | |
| 55 | 53 |
| 56 // Get the sequence containing the next task to execute. | 54 // Get the sequence containing the next task to execute. |
| 57 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_); | 55 scoped_refptr<Sequence> sequence = outer_->delegate_->GetWork(outer_); |
| 58 if (!sequence) { | 56 if (!sequence) { |
| 59 if (outer_->delegate_->CanDetach(outer_)) { | 57 if (outer_->delegate_->CanDetach(outer_)) { |
| 60 detached_thread = outer_->Detach(); | 58 detached_thread = outer_->Detach(); |
| 61 if (detached_thread) { | 59 if (detached_thread) { |
| 62 DCHECK_EQ(detached_thread.get(), this); | 60 DCHECK_EQ(detached_thread.get(), this); |
| 63 PlatformThread::Detach(thread_handle_); | 61 PlatformThread::Detach(thread_handle_); |
| 64 outer_ = nullptr; | 62 outer_ = nullptr; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 if (sleep_time.is_max()) { | 122 if (sleep_time.is_max()) { |
| 125 // Calling TimedWait with TimeDelta::Max is not recommended per | 123 // Calling TimedWait with TimeDelta::Max is not recommended per |
| 126 // http://crbug.com/465948. | 124 // http://crbug.com/465948. |
| 127 wake_up_event_.Wait(); | 125 wake_up_event_.Wait(); |
| 128 } else { | 126 } else { |
| 129 wake_up_event_.TimedWait(sleep_time); | 127 wake_up_event_.TimedWait(sleep_time); |
| 130 } | 128 } |
| 131 wake_up_event_.Reset(); | 129 wake_up_event_.Reset(); |
| 132 } | 130 } |
| 133 | 131 |
| 134 // Returns the desired thread priority based on the worker priority and the | 132 // Returns the priority to which the thread should be set based on the |
| 135 // current shutdown state. | 133 // SchedulerWorker's preferred priority, current shutdown state and platform |
|
gab
2016/08/03 13:35:24
oxford comma FTW (", and") :-)
fdoray
2016/08/03 18:42:48
Done.
| |
| 134 // capabilities. | |
| 136 ThreadPriority GetDesiredThreadPriority() { | 135 ThreadPriority GetDesiredThreadPriority() { |
| 137 DCHECK(outer_); | 136 DCHECK(outer_); |
| 138 | 137 |
| 139 if (outer_->task_tracker_->HasShutdownStarted() && | 138 const bool worker_priority_below_normal = |
| 140 static_cast<int>(outer_->thread_priority_) < | 139 static_cast<int>(outer_->thread_priority_) < |
| 141 static_cast<int>(ThreadPriority::NORMAL)) { | 140 static_cast<int>(ThreadPriority::NORMAL); |
| 141 | |
| 142 if (worker_priority_below_normal && | |
| 143 outer_->task_tracker_->HasShutdownStarted()) { | |
| 142 return ThreadPriority::NORMAL; | 144 return ThreadPriority::NORMAL; |
| 143 } | 145 } |
| 146 | |
| 147 #if defined(OS_POSIX) | |
|
gab
2016/08/03 13:35:24
Add a comment here why it's fine on Windows? This
fdoray
2016/08/03 18:42:49
n/a now that we have HandlesMultipleThreadPrioriti
| |
| 148 // To avoid priority inversion, all threads have a NORMAL priority when | |
| 149 // priority inheritance isn't available. | |
| 150 if (!Lock::PriorityInheritanceAvailable()) | |
| 151 return ThreadPriority::NORMAL; | |
| 152 #endif | |
| 153 | |
| 154 // To avoid shutdown hangs caused by BLOCK_SHUTDOWN tasks running on | |
| 155 // BACKGROUND threads, there are no BACKGROUND threads when thread priority | |
| 156 // can't be increased. | |
| 157 if (worker_priority_below_normal && | |
|
gab
2016/08/03 13:35:24
So "worker priority" is just the priority hint rig
fdoray
2016/08/03 18:42:48
Done
| |
| 158 !PlatformThread::CanIncreaseCurrentThreadPriority()) { | |
| 159 return ThreadPriority::NORMAL; | |
| 160 } | |
| 161 | |
| 144 return outer_->thread_priority_; | 162 return outer_->thread_priority_; |
|
gab
2016/08/03 13:35:24
So basically the point of |worker_priority_below_n
fdoray
2016/08/03 18:42:49
|worker_priority_below_normal| is gone
| |
| 145 } | 163 } |
| 146 | 164 |
| 147 // Increasing the thread priority requires the CAP_SYS_NICE capability on | |
| 148 // Linux. | |
| 149 #if !defined(OS_LINUX) | |
| 150 void UpdateThreadPriority(ThreadPriority desired_thread_priority) { | 165 void UpdateThreadPriority(ThreadPriority desired_thread_priority) { |
| 151 if (desired_thread_priority == current_thread_priority_) | 166 if (desired_thread_priority == current_thread_priority_) |
| 152 return; | 167 return; |
| 153 | 168 |
| 154 PlatformThread::SetCurrentThreadPriority(desired_thread_priority); | 169 PlatformThread::SetCurrentThreadPriority(desired_thread_priority); |
| 155 current_thread_priority_ = desired_thread_priority; | 170 current_thread_priority_ = desired_thread_priority; |
| 156 } | 171 } |
| 157 #endif // !defined(OS_LINUX) | |
| 158 | 172 |
| 159 PlatformThreadHandle thread_handle_; | 173 PlatformThreadHandle thread_handle_; |
| 160 | 174 |
| 161 SchedulerWorker* outer_; | 175 SchedulerWorker* outer_; |
| 162 | 176 |
| 163 // Event signaled to wake up this thread. | 177 // Event signaled to wake up this thread. |
| 164 WaitableEvent wake_up_event_; | 178 WaitableEvent wake_up_event_; |
| 165 | 179 |
| 166 // Current priority of this thread. May be different from | 180 // Current priority of this thread. May be different from |
| 167 // |outer_->thread_priority_| during shutdown. | 181 // |outer_->thread_priority_|. |
| 168 ThreadPriority current_thread_priority_; | 182 ThreadPriority current_thread_priority_; |
| 169 | 183 |
| 170 DISALLOW_COPY_AND_ASSIGN(Thread); | 184 DISALLOW_COPY_AND_ASSIGN(Thread); |
| 171 }; | 185 }; |
| 172 | 186 |
| 173 std::unique_ptr<SchedulerWorker> SchedulerWorker::Create( | 187 std::unique_ptr<SchedulerWorker> SchedulerWorker::Create( |
| 174 ThreadPriority thread_priority, | 188 ThreadPriority thread_priority, |
| 175 std::unique_ptr<Delegate> delegate, | 189 std::unique_ptr<Delegate> delegate, |
| 176 TaskTracker* task_tracker, | 190 TaskTracker* task_tracker, |
| 177 InitialState initial_state) { | 191 InitialState initial_state) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 256 CreateThread(); | 270 CreateThread(); |
| 257 } | 271 } |
| 258 | 272 |
| 259 bool SchedulerWorker::ShouldExitForTesting() const { | 273 bool SchedulerWorker::ShouldExitForTesting() const { |
| 260 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); | 274 AutoSchedulerLock auto_lock(should_exit_for_testing_lock_); |
| 261 return should_exit_for_testing_; | 275 return should_exit_for_testing_; |
| 262 } | 276 } |
| 263 | 277 |
| 264 } // namespace internal | 278 } // namespace internal |
| 265 } // namespace base | 279 } // namespace base |
| OLD | NEW |