| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_PERFORMANCE_MANAGER_RESOURCE_ATTRIBUTION_QUERY_SCHEDULER_H_ |
| #define COMPONENTS_PERFORMANCE_MANAGER_RESOURCE_ATTRIBUTION_QUERY_SCHEDULER_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/functional/callback_forward.h" |
| #include "base/functional/callback_helpers.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/sequence_checker.h" |
| #include "components/performance_manager/public/graph/graph_registered.h" |
| #include "components/performance_manager/public/resource_attribution/query_results.h" |
| #include "components/performance_manager/public/resource_attribution/resource_contexts.h" |
| #include "components/performance_manager/public/resource_attribution/resource_types.h" |
| #include "components/performance_manager/resource_attribution/cpu_measurement_monitor.h" |
| #include "components/performance_manager/resource_attribution/memory_measurement_provider.h" |
| #include "components/performance_manager/resource_attribution/performance_manager_aliases.h" |
| #include "components/performance_manager/resource_attribution/query_params.h" |
| #include "third_party/abseil-cpp/absl/container/flat_hash_map.h" |
| |
| namespace base { |
| class ScopedUmaHistogramTimer; |
| } |
| |
| namespace performance_manager { |
| class Graph; |
| } |
| |
| namespace resource_attribution { |
| class ContextCollection; |
| } |
| |
| namespace resource_attribution::internal { |
| |
| // QueryScheduler keeps track of all queries for a particular resource type and |
| // owns the machinery that performs measurements. |
| class QueryScheduler |
| : public performance_manager::GraphOwnedAndRegistered<QueryScheduler> { |
| public: |
| QueryScheduler(); |
| ~QueryScheduler() override; |
| |
| QueryScheduler(const QueryScheduler&) = delete; |
| QueryScheduler& operator=(const QueryScheduler&) = delete; |
| |
| // Returns the singleton QueryScheduler, or nullptr if none exists. This is |
| // equivalent to QueryScheduler::GetFromGraph(nullptr), but also works in |
| // unit tests using GraphTestHarness. |
| static QueryScheduler* Get(); |
| |
| base::WeakPtr<QueryScheduler> GetWeakPtr(); |
| |
| // Adds a scoped query for `query_params`. Increases the query count for all |
| // resource types and contexts referenced in `query_params`. |
| void AddScopedQuery(QueryParams* query_params); |
| |
| // Decreases the query count for all resource types and contexts referenced in |
| // `query_params` and deletes `query_params`. |
| void RemoveScopedQuery(std::unique_ptr<QueryParams> query_params); |
| |
| // Notifies the scheduler that a scoped query will begin repeatedly requesting |
| // results. The query now needs a QueryId to track what results it has |
| // received. If `passive_observer_callback` is not null, it will be called for |
| // results from all queries that match `query_params`. |
| void StartRepeatingQuery(QueryParams* query_params, |
| base::RepeatingCallback<void(const QueryResultMap&)> |
| passive_observer_callback = |
| base::NullCallback()); |
| |
| // Requests the latest results for the given `query_params`, and passes them |
| // to `callback`. |
| void RequestResults(const QueryParams& query_params, |
| base::OnceCallback<void(const QueryResultMap&)> callback); |
| |
| // GraphOwned: |
| void OnPassedToGraph(Graph* graph) final; |
| void OnTakenFromGraph(Graph* graph) final; |
| |
| // Gives tests direct access to `cpu_monitor_`. |
| CPUMeasurementMonitor& GetCPUMonitorForTesting(); |
| |
| // Gives tests direct access to `memory_provider_`. |
| MemoryMeasurementProvider& GetMemoryProviderForTesting(); |
| |
| // Gives tests access to the query count for `resource_type`. |
| uint32_t GetQueryCountForTesting(ResourceType resource_type) const; |
| |
| // Logs metrics on Resource Attribution's memory usage to UMA. |
| void RecordMemoryMetrics(); |
| |
| private: |
| // Increases the CPU query count. `cpu_monitor_` will start monitoring CPU |
| // usage when the count > 0. |
| void AddCPUQuery(); |
| |
| // Decreases the CPU query count. `cpu_monitor_` will stop monitoring CPU |
| // usage when the count == 0. |
| void RemoveCPUQuery(); |
| |
| // Increases the memory query count. |
| void AddMemoryQuery(); |
| |
| // Decreases the memory query count. |
| void RemoveMemoryQuery(); |
| |
| // Invoked from RequestResults when all results for `query_id` are received. |
| // `all_results` will contain a separate result map for each ResourceType that |
| // was requested. Combines them int a single result map associating all |
| // results for each context in `contexts`, and passes it to `callback`. |
| // `request_timer` logs the time from the beginning of RequestResults to the |
| // end of this function. |
| void OnResultsReceived( |
| const std::optional<QueryId>& query_id, |
| const ContextCollection& contexts, |
| std::unique_ptr<base::ScopedUmaHistogramTimer> request_timer, |
| base::OnceCallback<void(const QueryResultMap&)> callback, |
| std::vector<QueryResultMap> all_results); |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| // Copies of the queries that are observing all results. |
| absl::flat_hash_map< |
| QueryId, |
| std::pair<std::unique_ptr<QueryParams>, |
| base::RepeatingCallback<void(const QueryResultMap&)>>> |
| passive_observer_queries_ GUARDED_BY_CONTEXT(sequence_checker_); |
| |
| // CPU measurement machinery. |
| CPUMeasurementMonitor cpu_monitor_ GUARDED_BY_CONTEXT(sequence_checker_); |
| uint32_t cpu_query_count_ GUARDED_BY_CONTEXT(sequence_checker_) = 0; |
| |
| // Memory measurement machinery. |
| std::optional<MemoryMeasurementProvider> memory_provider_ |
| GUARDED_BY_CONTEXT(sequence_checker_); |
| uint32_t memory_query_count_ GUARDED_BY_CONTEXT(sequence_checker_) = 0; |
| |
| base::WeakPtrFactory<QueryScheduler> weak_factory_{this}; |
| }; |
| |
| } // namespace resource_attribution::internal |
| |
| #endif // COMPONENTS_PERFORMANCE_MANAGER_RESOURCE_ATTRIBUTION_QUERY_SCHEDULER_H_ |