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