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
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_GROUP_H_
6 #define CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_GROUP_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <map>
12 #include <vector>
13 
14 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/process/process_handle.h"
17 #include "base/time/time.h"
18 #include "build/build_config.h"
19 #include "chrome/browser/task_manager/providers/task.h"
20 #include "chrome/browser/task_manager/sampling/shared_sampler.h"
21 #include "chrome/browser/task_manager/sampling/task_group_sampler.h"
22 #include "chrome/browser/task_manager/task_manager_observer.h"
23 #include "components/nacl/common/buildflags.h"
24 
25 #if defined(OS_CHROMEOS)
26 #include "chrome/browser/task_manager/sampling/arc_shared_sampler.h"
27 #endif  // defined(OS_CHROMEOS)
28 
29 namespace gpu {
30 struct VideoMemoryUsageStats;
31 }
32 
33 namespace task_manager {
34 
35 // A mask for refresh flags that are not supported by VM tasks.
36 constexpr int kUnsupportedVMRefreshFlags =
37     REFRESH_TYPE_CPU | REFRESH_TYPE_SWAPPED_MEM | REFRESH_TYPE_GPU_MEMORY |
38     REFRESH_TYPE_V8_MEMORY | REFRESH_TYPE_SQLITE_MEMORY |
39     REFRESH_TYPE_WEBCACHE_STATS | REFRESH_TYPE_NETWORK_USAGE |
40     REFRESH_TYPE_NACL | REFRESH_TYPE_IDLE_WAKEUPS | REFRESH_TYPE_HANDLES |
41     REFRESH_TYPE_START_TIME | REFRESH_TYPE_CPU_TIME | REFRESH_TYPE_PRIORITY |
42 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
43     REFRESH_TYPE_FD_COUNT |
44 #endif
45     REFRESH_TYPE_HARD_FAULTS;
46 
47 class SharedSampler;
48 
49 // Defines a group of tasks tracked by the task manager which belong to the same
50 // process. This class lives on the UI thread.
51 class TaskGroup {
52  public:
53   TaskGroup(
54       base::ProcessHandle proc_handle,
55       base::ProcessId proc_id,
56       bool is_running_in_vm,
57       const base::RepeatingClosure& on_background_calculations_done,
58       const scoped_refptr<SharedSampler>& shared_sampler,
59       const scoped_refptr<base::SequencedTaskRunner>& blocking_pool_runner);
60   ~TaskGroup();
61 
62   // Adds and removes the given |task| to this group. |task| must be running on
63   // the same process represented by this group.
64   void AddTask(Task* task);
65   void RemoveTask(Task* task);
66 
67   void Refresh(const gpu::VideoMemoryUsageStats& gpu_memory_stats,
68                base::TimeDelta update_interval,
69                int64_t refresh_flags);
70 
71   Task* GetTaskById(TaskId task_id) const;
72 
73   // This is to be called after the task manager had informed its observers with
74   // OnTasksRefreshedWithBackgroundCalculations() to begin another cycle for
75   // this notification type.
76   void ClearCurrentBackgroundCalculationsFlags();
77 
78   // True if all enabled background operations calculating resource usage of the
79   // process represented by this TaskGroup have completed.
80   bool AreBackgroundCalculationsDone() const;
81 
82 #if defined(OS_CHROMEOS)
83   void SetArcSampler(ArcSharedSampler* sampler);
84 #endif  // defined(OS_CHROMEOS)
85 
process_handle()86   const base::ProcessHandle& process_handle() const { return process_handle_; }
process_id()87   const base::ProcessId& process_id() const { return process_id_; }
88 
tasks()89   const std::vector<Task*>& tasks() const { return tasks_; }
num_tasks()90   size_t num_tasks() const { return tasks().size(); }
empty()91   bool empty() const { return tasks().empty(); }
92 
platform_independent_cpu_usage()93   double platform_independent_cpu_usage() const {
94     return platform_independent_cpu_usage_;
95   }
start_time()96   base::Time start_time() const { return start_time_; }
cpu_time()97   base::TimeDelta cpu_time() const { return cpu_time_; }
set_footprint_bytes(int64_t footprint)98   void set_footprint_bytes(int64_t footprint) { memory_footprint_ = footprint; }
footprint_bytes()99   int64_t footprint_bytes() const { return memory_footprint_; }
100 #if defined(OS_CHROMEOS)
swapped_bytes()101   int64_t swapped_bytes() const { return swapped_mem_bytes_; }
102 #endif
gpu_memory()103   int64_t gpu_memory() const { return gpu_memory_; }
gpu_memory_has_duplicates()104   bool gpu_memory_has_duplicates() const { return gpu_memory_has_duplicates_; }
per_process_network_usage_rate()105   int64_t per_process_network_usage_rate() const {
106     return per_process_network_usage_rate_;
107   }
cumulative_per_process_network_usage()108   int64_t cumulative_per_process_network_usage() const {
109     return cumulative_per_process_network_usage_;
110   }
is_backgrounded()111   bool is_backgrounded() const { return is_backgrounded_; }
112 
113 #if defined(OS_WIN)
gdi_current_handles()114   int64_t gdi_current_handles() const { return gdi_current_handles_; }
gdi_peak_handles()115   int64_t gdi_peak_handles() const { return gdi_peak_handles_; }
user_current_handles()116   int64_t user_current_handles() const { return user_current_handles_; }
user_peak_handles()117   int64_t user_peak_handles() const { return user_peak_handles_; }
hard_faults_per_second()118   int64_t hard_faults_per_second() const { return hard_faults_per_second_; }
119 #endif  // defined(OS_WIN)
120 
121 #if BUILDFLAG(ENABLE_NACL)
nacl_debug_stub_port()122   int nacl_debug_stub_port() const { return nacl_debug_stub_port_; }
123 #endif  // BUILDFLAG(ENABLE_NACL)
124 
125 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
open_fd_count()126   int open_fd_count() const { return open_fd_count_; }
127 #endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
128 
idle_wakeups_per_second()129   int idle_wakeups_per_second() const { return idle_wakeups_per_second_; }
130 
131  private:
132   void RefreshGpuMemory(const gpu::VideoMemoryUsageStats& gpu_memory_stats);
133 
134   void RefreshWindowsHandles();
135 
136 #if BUILDFLAG(ENABLE_NACL)
137   // |child_process_unique_id| see Task::GetChildProcessUniqueID().
138   void RefreshNaClDebugStubPort(int child_process_unique_id);
139   void OnRefreshNaClDebugStubPortDone(int port);
140 #endif
141 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
142   void OnOpenFdCountRefreshDone(int open_fd_count);
143 #endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
144 
145   void OnCpuRefreshDone(double cpu_usage);
146   void OnSwappedMemRefreshDone(int64_t swapped_mem_bytes);
147   void OnProcessPriorityDone(bool is_backgrounded);
148   void OnIdleWakeupsRefreshDone(int idle_wakeups_per_second);
149 
150   void OnSamplerRefreshDone(
151       base::Optional<SharedSampler::SamplingResult> results);
152 
153 #if defined(OS_CHROMEOS)
154   void OnArcSamplerRefreshDone(
155       base::Optional<ArcSharedSampler::MemoryFootprintBytes> results);
156 #endif  // defined(OS_CHROMEOS)
157 
158   void OnBackgroundRefreshTypeFinished(int64_t finished_refresh_type);
159 
160   // The process' handle and ID.
161   base::ProcessHandle process_handle_;
162   base::ProcessId process_id_;
163   bool is_running_in_vm_;
164 
165   // This is a callback into the TaskManagerImpl to inform it that the
166   // background calculations for this TaskGroup has finished.
167   const base::RepeatingClosure on_background_calculations_done_;
168 
169   scoped_refptr<TaskGroupSampler> worker_thread_sampler_;
170 
171   scoped_refptr<SharedSampler> shared_sampler_;
172 #if defined(OS_CHROMEOS)
173   // Shared sampler that retrieves memory footprint for all ARC processes.
174   ArcSharedSampler* arc_shared_sampler_;  // Not owned
175 #endif                                    // defined(OS_CHROMEOS)
176 
177   // Lists the Tasks in this TaskGroup.
178   // Tasks are not owned by the TaskGroup. They're owned by the TaskProviders.
179   std::vector<Task*> tasks_;
180 
181   // Flags will be used to determine when the background calculations has
182   // completed for the enabled refresh types for this TaskGroup.
183   int64_t expected_on_bg_done_flags_;
184   int64_t current_on_bg_done_flags_;
185 
186   // The per process resources usages.
187   double platform_independent_cpu_usage_;
188   base::Time start_time_;     // Only calculated On Windows now.
189   base::TimeDelta cpu_time_;  // Only calculated On Windows now.
190   int64_t swapped_mem_bytes_;
191   int64_t memory_footprint_;
192   int64_t gpu_memory_;
193   // The network usage in bytes per second as the sum of all network usages of
194   // the individual tasks sharing the same process.
195   int64_t per_process_network_usage_rate_;
196 
197   // A continuously updating sum of all bytes that have been downloaded and
198   // uploaded by all tasks in this process.
199   int64_t cumulative_per_process_network_usage_;
200 
201 #if defined(OS_WIN)
202   // Windows GDI and USER Handles.
203   int64_t gdi_current_handles_;
204   int64_t gdi_peak_handles_;
205   int64_t user_current_handles_;
206   int64_t user_peak_handles_;
207   int64_t hard_faults_per_second_;
208 #endif  // defined(OS_WIN)
209 #if BUILDFLAG(ENABLE_NACL)
210   int nacl_debug_stub_port_;
211 #endif  // BUILDFLAG(ENABLE_NACL)
212 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
213   // The number of file descriptors currently open by the process.
214   int open_fd_count_;
215 #endif  // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_BSD)
216   int idle_wakeups_per_second_;
217   bool gpu_memory_has_duplicates_;
218   bool is_backgrounded_;
219 
220   // Always keep this the last member of this class so that it's the first to be
221   // destroyed.
222   base::WeakPtrFactory<TaskGroup> weak_ptr_factory_{this};
223 
224   DISALLOW_COPY_AND_ASSIGN(TaskGroup);
225 };
226 
227 }  // namespace task_manager
228 
229 #endif  // CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_GROUP_H_
230