Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "chrome/browser/task_management/sampling/task_group.h" | 5 #include "chrome/browser/task_management/sampling/task_group.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| 11 #include "chrome/browser/task_management/task_manager_observer.h" | 11 #include "chrome/browser/task_management/task_manager_observer.h" |
| 12 #include "components/nacl/browser/nacl_browser.h" | 12 #include "components/nacl/browser/nacl_browser.h" |
| 13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 | 14 |
| 15 namespace task_management { | 15 namespace task_management { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // A mask for the refresh types that are done in the background thread. | |
| 20 const int kBackgroundRefreshTypesMask = | |
| 21 REFRESH_TYPE_CPU | | |
| 22 REFRESH_TYPE_MEMORY | | |
| 23 REFRESH_TYPE_IDLE_WAKEUPS | | |
| 24 #if defined(OS_LINUX) | |
| 25 REFRESH_TYPE_FD_COUNT | | |
| 26 #endif // defined(OS_LINUX) | |
| 27 REFRESH_TYPE_PRIORITY; | |
| 28 | |
| 19 inline bool IsResourceRefreshEnabled(RefreshType refresh_type, | 29 inline bool IsResourceRefreshEnabled(RefreshType refresh_type, |
| 20 int refresh_flags) { | 30 int refresh_flags) { |
| 21 return (refresh_flags & refresh_type) != 0; | 31 return (refresh_flags & refresh_type) != 0; |
| 22 } | 32 } |
| 23 | 33 |
| 24 #if defined(OS_WIN) | 34 #if defined(OS_WIN) |
| 25 // Gets the GDI and USER Handles on Windows at one shot. | 35 // Gets the GDI and USER Handles on Windows at one shot. |
| 26 void GetWindowsHandles(base::ProcessHandle handle, | 36 void GetWindowsHandles(base::ProcessHandle handle, |
| 27 int64_t* out_gdi_current, | 37 int64_t* out_gdi_current, |
| 28 int64_t* out_gdi_peak, | 38 int64_t* out_gdi_peak, |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 49 CloseHandle(process_with_query_rights); | 59 CloseHandle(process_with_query_rights); |
| 50 } | 60 } |
| 51 } | 61 } |
| 52 #endif // defined(OS_WIN) | 62 #endif // defined(OS_WIN) |
| 53 | 63 |
| 54 } // namespace | 64 } // namespace |
| 55 | 65 |
| 56 TaskGroup::TaskGroup( | 66 TaskGroup::TaskGroup( |
| 57 base::ProcessHandle proc_handle, | 67 base::ProcessHandle proc_handle, |
| 58 base::ProcessId proc_id, | 68 base::ProcessId proc_id, |
| 69 const base::Closure& on_background_calculations_done, | |
| 59 const scoped_refptr<base::SequencedTaskRunner>& blocking_pool_runner) | 70 const scoped_refptr<base::SequencedTaskRunner>& blocking_pool_runner) |
| 60 : process_handle_(proc_handle), | 71 : process_handle_(proc_handle), |
| 61 process_id_(proc_id), | 72 process_id_(proc_id), |
| 73 on_background_calculations_done_(on_background_calculations_done), | |
| 62 worker_thread_sampler_(nullptr), | 74 worker_thread_sampler_(nullptr), |
| 63 tasks_(), | 75 expected_on_bg_done_flags_(kBackgroundRefreshTypesMask), |
| 76 current_on_bg_done_flags_(0), | |
| 64 cpu_usage_(0.0), | 77 cpu_usage_(0.0), |
| 65 memory_usage_(), | 78 memory_usage_(), |
| 66 gpu_memory_(-1), | 79 gpu_memory_(-1), |
| 67 per_process_network_usage_(-1), | 80 per_process_network_usage_(-1), |
| 68 #if defined(OS_WIN) | 81 #if defined(OS_WIN) |
| 69 gdi_current_handles_(-1), | 82 gdi_current_handles_(-1), |
| 70 gdi_peak_handles_(-1), | 83 gdi_peak_handles_(-1), |
| 71 user_current_handles_(-1), | 84 user_current_handles_(-1), |
| 72 user_peak_handles_(-1), | 85 user_peak_handles_(-1), |
| 73 #endif // defined(OS_WIN) | 86 #endif // defined(OS_WIN) |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 | 129 |
| 117 tasks_.erase(task->task_id()); | 130 tasks_.erase(task->task_id()); |
| 118 } | 131 } |
| 119 | 132 |
| 120 void TaskGroup::Refresh( | 133 void TaskGroup::Refresh( |
| 121 const content::GPUVideoMemoryUsageStats& gpu_memory_stats, | 134 const content::GPUVideoMemoryUsageStats& gpu_memory_stats, |
| 122 base::TimeDelta update_interval, | 135 base::TimeDelta update_interval, |
| 123 int64_t refresh_flags) { | 136 int64_t refresh_flags) { |
| 124 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 137 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 125 | 138 |
| 139 expected_on_bg_done_flags_ = refresh_flags & kBackgroundRefreshTypesMask; | |
|
ncarter (slow)
2016/02/17 21:21:19
Is it possible for the next Refresh event to fire,
afakhry
2016/02/19 17:35:09
I think it could, since we are using a sequenced t
ncarter (slow)
2016/02/19 18:19:03
OK.
I do worry a bit about the case where samplin
| |
| 140 | |
| 126 // First refresh the enabled non-expensive resources usages on the UI thread. | 141 // First refresh the enabled non-expensive resources usages on the UI thread. |
| 127 // 1- Refresh all the tasks as well as the total network usage (if enabled). | 142 // 1- Refresh all the tasks as well as the total network usage (if enabled). |
| 128 const bool network_usage_refresh_enabled = | 143 const bool network_usage_refresh_enabled = |
| 129 IsResourceRefreshEnabled(REFRESH_TYPE_NETWORK_USAGE, refresh_flags); | 144 IsResourceRefreshEnabled(REFRESH_TYPE_NETWORK_USAGE, refresh_flags); |
| 130 per_process_network_usage_ = network_usage_refresh_enabled ? 0 : -1; | 145 per_process_network_usage_ = network_usage_refresh_enabled ? 0 : -1; |
| 131 for (auto& task_pair : tasks_) { | 146 for (auto& task_pair : tasks_) { |
| 132 Task* task = task_pair.second; | 147 Task* task = task_pair.second; |
| 133 task->Refresh(update_interval, refresh_flags); | 148 task->Refresh(update_interval, refresh_flags); |
| 134 | 149 |
| 135 if (network_usage_refresh_enabled && task->ReportsNetworkUsage()) { | 150 if (network_usage_refresh_enabled && task->ReportsNetworkUsage()) |
| 136 per_process_network_usage_ += task->network_usage(); | 151 per_process_network_usage_ += task->network_usage(); |
| 137 } | |
| 138 } | 152 } |
| 139 | 153 |
| 140 // 2- Refresh GPU memory (if enabled). | 154 // 2- Refresh GPU memory (if enabled). |
| 141 if (IsResourceRefreshEnabled(REFRESH_TYPE_GPU_MEMORY, refresh_flags)) | 155 if (IsResourceRefreshEnabled(REFRESH_TYPE_GPU_MEMORY, refresh_flags)) |
| 142 RefreshGpuMemory(gpu_memory_stats); | 156 RefreshGpuMemory(gpu_memory_stats); |
| 143 | 157 |
| 144 // 3- Refresh Windows handles (if enabled). | 158 // 3- Refresh Windows handles (if enabled). |
| 145 #if defined(OS_WIN) | 159 #if defined(OS_WIN) |
| 146 if (IsResourceRefreshEnabled(REFRESH_TYPE_HANDLES, refresh_flags)) | 160 if (IsResourceRefreshEnabled(REFRESH_TYPE_HANDLES, refresh_flags)) |
| 147 RefreshWindowsHandles(); | 161 RefreshWindowsHandles(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 nacl::NaClBrowser* nacl_browser = nacl::NaClBrowser::GetInstance(); | 221 nacl::NaClBrowser* nacl_browser = nacl::NaClBrowser::GetInstance(); |
| 208 nacl_debug_stub_port_ = | 222 nacl_debug_stub_port_ = |
| 209 nacl_browser->GetProcessGdbDebugStubPort(child_process_unique_id); | 223 nacl_browser->GetProcessGdbDebugStubPort(child_process_unique_id); |
| 210 #endif // !defined(DISABLE_NACL) | 224 #endif // !defined(DISABLE_NACL) |
| 211 } | 225 } |
| 212 | 226 |
| 213 void TaskGroup::OnCpuRefreshDone(double cpu_usage) { | 227 void TaskGroup::OnCpuRefreshDone(double cpu_usage) { |
| 214 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 228 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 215 | 229 |
| 216 cpu_usage_ = cpu_usage; | 230 cpu_usage_ = cpu_usage; |
| 231 OnBackgroundRefreshTypeFinished(REFRESH_TYPE_CPU); | |
| 217 } | 232 } |
| 218 | 233 |
| 219 void TaskGroup::OnMemoryUsageRefreshDone(MemoryUsageStats memory_usage) { | 234 void TaskGroup::OnMemoryUsageRefreshDone(MemoryUsageStats memory_usage) { |
| 220 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 235 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 221 | 236 |
| 222 memory_usage_ = memory_usage; | 237 memory_usage_ = memory_usage; |
| 238 OnBackgroundRefreshTypeFinished(REFRESH_TYPE_MEMORY); | |
| 223 } | 239 } |
| 224 | 240 |
| 225 void TaskGroup::OnIdleWakeupsRefreshDone(int idle_wakeups_per_second) { | 241 void TaskGroup::OnIdleWakeupsRefreshDone(int idle_wakeups_per_second) { |
| 226 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 242 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 227 | 243 |
| 228 idle_wakeups_per_second_ = idle_wakeups_per_second; | 244 idle_wakeups_per_second_ = idle_wakeups_per_second; |
| 245 OnBackgroundRefreshTypeFinished(REFRESH_TYPE_IDLE_WAKEUPS); | |
| 229 } | 246 } |
| 230 | 247 |
| 231 #if defined(OS_LINUX) | 248 #if defined(OS_LINUX) |
| 232 void TaskGroup::OnOpenFdCountRefreshDone(int open_fd_count) { | 249 void TaskGroup::OnOpenFdCountRefreshDone(int open_fd_count) { |
| 233 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 250 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 234 | 251 |
| 235 open_fd_count_ = open_fd_count; | 252 open_fd_count_ = open_fd_count; |
| 253 OnBackgroundRefreshTypeFinished(REFRESH_TYPE_FD_COUNT); | |
| 236 } | 254 } |
| 237 #endif // defined(OS_LINUX) | 255 #endif // defined(OS_LINUX) |
| 238 | 256 |
| 239 void TaskGroup::OnProcessPriorityDone(bool is_backgrounded) { | 257 void TaskGroup::OnProcessPriorityDone(bool is_backgrounded) { |
| 240 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 258 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 241 | 259 |
| 242 is_backgrounded_ = is_backgrounded; | 260 is_backgrounded_ = is_backgrounded; |
| 261 OnBackgroundRefreshTypeFinished(REFRESH_TYPE_PRIORITY); | |
| 262 } | |
| 263 | |
| 264 void TaskGroup::OnBackgroundRefreshTypeFinished(int64_t finished_refresh_type) { | |
| 265 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 266 | |
| 267 current_on_bg_done_flags_ |= finished_refresh_type; | |
|
ncarter (slow)
2016/02/17 21:21:19
current_on_bg_done_flags_ is never cleared back to
afakhry
2016/02/19 17:35:09
Oh sorry it was clear enough. |current_on_bg_done_
| |
| 268 if (current_on_bg_done_flags_ == expected_on_bg_done_flags_) | |
|
ncarter (slow)
2016/02/17 21:21:19
What if refresh_flags (at Refresh() time) didn't s
afakhry
2016/02/19 17:35:09
Thanks! I added a line to TaskGroup:Refresh() to t
| |
| 269 on_background_calculations_done_.Run(); | |
| 243 } | 270 } |
| 244 | 271 |
| 245 } // namespace task_management | 272 } // namespace task_management |
| OLD | NEW |