blob: a00d0e75d090559bddd01a46740164f974ad8ae4 [file] [log] [blame]
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_GROUP_H_
#define CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_GROUP_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <optional>
#include <vector>
#include "base/byte_count.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process_handle.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/task_manager/providers/task.h"
#include "chrome/browser/task_manager/sampling/shared_sampler.h"
#include "chrome/browser/task_manager/sampling/task_group_sampler.h"
#include "chrome/browser/task_manager/task_manager_observer.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/task_manager/sampling/arc_shared_sampler.h"
#endif // BUILDFLAG(IS_CHROMEOS)
namespace gpu {
struct VideoMemoryUsageStats;
}
namespace task_manager {
// A mask for refresh flags that are not supported by VM tasks.
inline constexpr int kUnsupportedVMRefreshFlags =
REFRESH_TYPE_CPU | REFRESH_TYPE_SWAPPED_MEM | REFRESH_TYPE_GPU_MEMORY |
REFRESH_TYPE_V8_MEMORY | REFRESH_TYPE_SQLITE_MEMORY |
REFRESH_TYPE_WEBCACHE_STATS | REFRESH_TYPE_NETWORK_USAGE |
REFRESH_TYPE_IDLE_WAKEUPS | REFRESH_TYPE_HANDLES | REFRESH_TYPE_START_TIME |
REFRESH_TYPE_CPU_TIME | REFRESH_TYPE_PRIORITY |
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
REFRESH_TYPE_FD_COUNT |
#endif
REFRESH_TYPE_HARD_FAULTS;
class SharedSampler;
// Defines a group of tasks tracked by the task manager which belong to the same
// process. This class lives on the UI thread.
class TaskGroup {
public:
TaskGroup(
base::ProcessHandle proc_handle,
base::ProcessId proc_id,
bool is_running_in_vm,
const base::RepeatingClosure& on_background_calculations_done,
const scoped_refptr<SharedSampler>& shared_sampler,
const scoped_refptr<base::SequencedTaskRunner>& blocking_pool_runner);
TaskGroup(const TaskGroup&) = delete;
TaskGroup& operator=(const TaskGroup&) = delete;
~TaskGroup();
// Adds and removes the given |task| to this group. |task| must be running on
// the same process represented by this group.
void AddTask(Task* task);
void RemoveTask(Task* task);
void Refresh(const gpu::VideoMemoryUsageStats& gpu_memory_stats,
base::TimeDelta update_interval,
int64_t refresh_flags);
Task* GetTaskById(TaskId task_id) const;
// This is to be called after the task manager had informed its observers with
// OnTasksRefreshedWithBackgroundCalculations() to begin another cycle for
// this notification type.
void ClearCurrentBackgroundCalculationsFlags();
// True if all enabled background operations calculating resource usage of the
// process represented by this TaskGroup have completed.
bool AreBackgroundCalculationsDone() const;
#if BUILDFLAG(IS_CHROMEOS)
void SetArcSampler(ArcSharedSampler* sampler);
#endif // BUILDFLAG(IS_CHROMEOS)
const base::ProcessHandle& process_handle() const { return process_handle_; }
const base::ProcessId& process_id() const { return process_id_; }
const std::vector<raw_ptr<Task, VectorExperimental>>& tasks() const {
return tasks_;
}
size_t num_tasks() const { return tasks().size(); }
bool empty() const { return tasks().empty(); }
double platform_independent_cpu_usage() const {
return platform_independent_cpu_usage_;
}
void set_platform_independent_cpu_usage(double cpu_usage) {
platform_independent_cpu_usage_ = cpu_usage;
}
base::Time start_time() const { return start_time_; }
base::TimeDelta cpu_time() const { return cpu_time_; }
void set_footprint(base::ByteCount footprint) {
memory_footprint_ = footprint;
}
base::ByteCount footprint_bytes() const { return memory_footprint_; }
#if BUILDFLAG(IS_CHROMEOS)
base::ByteCount swapped_bytes() const { return swapped_mem_; }
void set_swapped_bytes(base::ByteCount swapped_bytes) {
swapped_mem_ = swapped_bytes;
}
#endif // BUILDFLAG(IS_CHROMEOS)
base::ByteCount gpu_memory() const { return gpu_memory_; }
void set_gpu_memory(base::ByteCount gpu_mem_bytes) {
gpu_memory_ = gpu_mem_bytes;
}
bool gpu_memory_has_duplicates() const { return gpu_memory_has_duplicates_; }
void set_gpu_memory_has_duplicates(bool has_duplicates) {
gpu_memory_has_duplicates_ = has_duplicates;
}
base::ByteCount per_process_network_usage_rate() const {
return per_process_network_usage_rate_;
}
base::ByteCount cumulative_per_process_network_usage() const {
return cumulative_per_process_network_usage_;
}
bool is_backgrounded() const { return is_backgrounded_; }
void set_is_backgrounded(bool is_backgrounded) {
is_backgrounded_ = is_backgrounded;
}
#if BUILDFLAG(IS_WIN)
int64_t gdi_current_handles() const { return gdi_current_handles_; }
int64_t gdi_peak_handles() const { return gdi_peak_handles_; }
int64_t user_current_handles() const { return user_current_handles_; }
int64_t user_peak_handles() const { return user_peak_handles_; }
int64_t hard_faults_per_second() const { return hard_faults_per_second_; }
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
int open_fd_count() const { return open_fd_count_; }
void set_open_fd_count(int open_fd_count) { open_fd_count_ = open_fd_count; }
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
int idle_wakeups_per_second() const { return idle_wakeups_per_second_; }
void set_idle_wakeups_per_second(int idle_wakeups) {
idle_wakeups_per_second_ = idle_wakeups;
}
private:
void RefreshGpuMemory(const gpu::VideoMemoryUsageStats& gpu_memory_stats);
void RefreshWindowsHandles();
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
void OnOpenFdCountRefreshDone(int open_fd_count);
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
void OnCpuRefreshDone(double cpu_usage);
void OnSwappedMemRefreshDone(base::ByteCount swapped_mem_bytes);
void OnProcessPriorityDone(base::Process::Priority priority);
void OnIdleWakeupsRefreshDone(int idle_wakeups_per_second);
void OnSamplerRefreshDone(
std::optional<SharedSampler::SamplingResult> results);
#if BUILDFLAG(IS_CHROMEOS)
void OnArcSamplerRefreshDone(
std::optional<ArcSharedSampler::MemoryFootprintBytes> results);
#endif // BUILDFLAG(IS_CHROMEOS)
void OnBackgroundRefreshTypeFinished(int64_t finished_refresh_type);
// The process' handle and ID.
base::ProcessHandle process_handle_;
base::ProcessId process_id_;
bool is_running_in_vm_;
// This is a callback into the TaskManagerImpl to inform it that the
// background calculations for this TaskGroup has finished.
const base::RepeatingClosure on_background_calculations_done_;
scoped_refptr<TaskGroupSampler> worker_thread_sampler_;
scoped_refptr<SharedSampler> shared_sampler_;
#if BUILDFLAG(IS_CHROMEOS)
// Shared sampler that retrieves memory footprint for all ARC processes.
raw_ptr<ArcSharedSampler> arc_shared_sampler_ = nullptr; // Not owned
#endif // BUILDFLAG(IS_CHROMEOS)
// Lists the Tasks in this TaskGroup.
// Tasks are not owned by the TaskGroup. They're owned by the TaskProviders.
std::vector<raw_ptr<Task, VectorExperimental>> tasks_;
// Flags will be used to determine when the background calculations has
// completed for the enabled refresh types for this TaskGroup.
int64_t expected_on_bg_done_flags_;
int64_t current_on_bg_done_flags_;
// The per process resources usages.
double platform_independent_cpu_usage_ =
std::numeric_limits<double>::quiet_NaN();
base::Time start_time_; // Only calculated On Windows now.
base::TimeDelta cpu_time_; // Only calculated On Windows now.
base::ByteCount swapped_mem_ = base::ByteCount(-1);
base::ByteCount memory_footprint_ = base::ByteCount(-1);
base::ByteCount gpu_memory_ = base::ByteCount(-1);
// The network usage in bytes per second as the sum of all network usages of
// the individual tasks sharing the same process.
base::ByteCount per_process_network_usage_rate_ = base::ByteCount(-1);
// A continuously updating sum of all bytes that have been downloaded and
// uploaded by all tasks in this process.
base::ByteCount cumulative_per_process_network_usage_ = base::ByteCount(0);
#if BUILDFLAG(IS_WIN)
// Windows GDI and USER Handles.
int64_t gdi_current_handles_ = -1;
int64_t gdi_peak_handles_ = -1;
int64_t user_current_handles_ = -1;
int64_t user_peak_handles_ = -1;
int64_t hard_faults_per_second_ = -1;
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
// The number of file descriptors currently open by the process.
int open_fd_count_ = -1;
#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC)
int idle_wakeups_per_second_ = -1;
bool gpu_memory_has_duplicates_ = false;
bool is_backgrounded_ = false;
// Always keep this the last member of this class so that it's the first to be
// destroyed.
base::WeakPtrFactory<TaskGroup> weak_ptr_factory_{this};
};
} // namespace task_manager
#endif // CHROME_BROWSER_TASK_MANAGER_SAMPLING_TASK_GROUP_H_