1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
// Copyright 2016 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_SHARED_SAMPLER_H_
#define CHROME_BROWSER_TASK_MANAGER_SAMPLING_SHARED_SAMPLER_H_
#include <map>
#include <memory>
#include <optional>
#include <utility>
#include <vector>
#include "base/containers/span.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/memory/ref_counted.h"
#include "base/process/process_handle.h"
#include "base/sequence_checker.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "build/build_config.h"
namespace task_manager {
struct ProcessDataSnapshot;
// Defines sampler that will calculate resources for all processes all at once,
// on the worker thread. Created by TaskManagerImpl on the UI thread, but used
// mainly on a blocking pool thread.
//
// This exists because on Windows it is much faster to collect a group of
// process metrics for all processes all at once using NtQuerySystemInformation
// than to query the same data for for each process individually and because
// some types like Idle Wakeups can only be collected this way.
class SharedSampler : public base::RefCountedThreadSafe<SharedSampler> {
public:
explicit SharedSampler(
const scoped_refptr<base::SequencedTaskRunner>& blocking_pool_runner);
SharedSampler(const SharedSampler&) = delete;
SharedSampler& operator=(const SharedSampler&) = delete;
struct SamplingResult {
base::TimeDelta cpu_time;
int64_t hard_faults_per_second;
int idle_wakeups_per_second;
base::Time start_time;
};
using OnSamplingCompleteCallback =
base::RepeatingCallback<void(std::optional<SamplingResult>)>;
// Returns a combination of refresh flags supported by the shared sampler.
int64_t GetSupportedFlags() const;
// Registers task group specific callbacks.
void RegisterCallback(base::ProcessId process_id,
OnSamplingCompleteCallback on_sampling_complete);
// Unregisters task group specific callbacks.
void UnregisterCallback(base::ProcessId process_id);
// Triggers a refresh of the expensive process' stats, on the worker thread.
void Refresh(base::ProcessId process_id, int64_t refresh_flags);
#if BUILDFLAG(IS_WIN)
// Specifies a function to use in place of NtQuerySystemInformation.
typedef int (*QuerySystemInformationForTest)(base::span<uint8_t> buffer);
static void SetQuerySystemInformationForTest(
QuerySystemInformationForTest query_system_information);
#endif // BUILDFLAG(IS_WIN)
private:
friend class base::RefCountedThreadSafe<SharedSampler>;
~SharedSampler();
typedef std::map<base::ProcessId, OnSamplingCompleteCallback> CallbacksMap;
#if BUILDFLAG(IS_WIN)
// Contains all results of refresh for a single process.
struct ProcessIdAndSamplingResult {
base::ProcessId process_id;
SamplingResult data;
};
typedef std::vector<ProcessIdAndSamplingResult> AllSamplingResults;
// Posted on the worker thread to do the actual refresh.
AllSamplingResults RefreshOnWorkerThread();
// Called on UI thread when the refresh is done.
void OnRefreshDone(AllSamplingResults sampling_results);
// Clear cached data.
void ClearState();
// Used to filter process information.
static std::vector<base::FilePath> GetSupportedImageNames();
bool IsSupportedImageName(base::FilePath::StringViewType image_name) const;
// Captures a snapshot of data for all chrome processes.
// Runs on the worker thread.
std::unique_ptr<ProcessDataSnapshot> CaptureSnapshot();
// Produce refresh results by diffing two snapshots.
static AllSamplingResults MakeResultsFromTwoSnapshots(
const ProcessDataSnapshot& prev_snapshot,
const ProcessDataSnapshot& snapshot);
// Produce refresh results from one snapshot.
// This is used only the first time when only one snapshot is available.
static AllSamplingResults MakeResultsFromSnapshot(
const ProcessDataSnapshot& snapshot);
// Accumulates callbacks passed from TaskGroup objects passed via
// RegisterCallbacks calls.
CallbacksMap callbacks_map_;
// Refresh flags passed via Refresh.
int64_t refresh_flags_;
// Snapshot of previously captured resources used to calculate the delta.
std::unique_ptr<ProcessDataSnapshot> previous_snapshot_;
// Size of the buffer previously used to query system information.
size_t previous_buffer_size_;
// Image names that CaptureSnapshot uses to filter processes.
const std::vector<base::FilePath> supported_image_names_;
// The specific blocking pool SequencedTaskRunner that will be used to post
// the refresh tasks onto serially.
scoped_refptr<base::SequencedTaskRunner> blocking_pool_runner_;
// To assert we're running on the correct thread.
SEQUENCE_CHECKER(worker_pool_sequenced_checker_);
#endif // BUILDFLAG(IS_WIN)
};
} // namespace task_manager
#endif // CHROME_BROWSER_TASK_MANAGER_SAMPLING_SHARED_SAMPLER_H_
|