File: queries.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (219 lines) | stat: -rw-r--r-- 8,304 bytes parent folder | download | duplicates (4)
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
// 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_PUBLIC_RESOURCE_ATTRIBUTION_QUERIES_H_
#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RESOURCE_ATTRIBUTION_QUERIES_H_

#include <memory>

#include "base/functional/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/observer_list_threadsafe.h"
#include "base/scoped_observation.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/types/pass_key.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/public/resource_attribution/type_helpers.h"

namespace resource_attribution {

namespace internal {
class QueryParams;
class QueryScheduler;
}

class QueryBuilder;

// An observer that's notified by ScopedResourceUsageQuery whenever new results
// are available.
class QueryResultObserver {
 public:
  virtual ~QueryResultObserver() = default;
  virtual void OnResourceUsageUpdated(const QueryResultMap& results) = 0;
};

// Repeatedly makes resource attribution queries on a schedule as long as it's
// in scope. All methods must be called on the UI thread.
class ScopedResourceUsageQuery {
 public:
  ~ScopedResourceUsageQuery();

  // Move-only.
  ScopedResourceUsageQuery(ScopedResourceUsageQuery&&);
  ScopedResourceUsageQuery& operator=(ScopedResourceUsageQuery&&);
  ScopedResourceUsageQuery(const ScopedResourceUsageQuery&) = delete;
  ScopedResourceUsageQuery& operator=(const ScopedResourceUsageQuery&) = delete;

  // Adds an observer that will be notified whenever query results are updated.
  void AddObserver(QueryResultObserver* observer);

  // Removes an observer that was added with AddObserver().
  void RemoveObserver(QueryResultObserver* observer);

  // Starts sending scheduled queries. They will repeat as long as the
  // ScopedResourceUsageQuery object exists.
  // TODO(crbug.com/40926264): Repeating queries will be sent on a timer with
  // `delay` between queries. Replace this with the full scheduling hints
  // described at https://bit.ly/resource-attribution-api#heading=h.upcqivkhbs4t
  void Start(base::TimeDelta delay);

  // Sends an immediate query, in addition to the schedule of repeated queries
  // triggered by Start().
  void QueryOnce();

  // Restricted implementation methods:

  // Gives tests access to validate the implementation.
  internal::QueryParams* GetParamsForTesting() const;

  // Returns the minimum delay between QueryOnce() calls for kMemorySummary
  // resources.
  static base::TimeDelta GetMinMemoryQueryDelayForTesting();

  // Instantiate this to set the minimum delay between QueryOnce() calls for
  // kMemorySummary resources to 0 during a test.
  class ScopedDisableMemoryQueryDelayForTesting {
   public:
    ScopedDisableMemoryQueryDelayForTesting();
    ~ScopedDisableMemoryQueryDelayForTesting();

   private:
    base::TimeDelta previous_delay_;
  };

  // Private constructor for QueryBuilder. Use QueryBuilder::CreateScopedQuery()
  // to create a query.
  ScopedResourceUsageQuery(base::PassKey<QueryBuilder>,
                           std::unique_ptr<internal::QueryParams> params);

 private:
  // TODO(crbug.com/40755583): This no longer needs to be thread-safe.
  using ObserverList = base::ObserverListThreadSafe<
      QueryResultObserver,
      base::RemoveObserverPolicy::kAddingSequenceOnly>;

  FRIEND_TEST_ALL_PREFIXES(ResourceAttrQueriesPMTest, ScopedQueryIsMovable);

  class ThrottledTimer;

  // Notifies `observer_list` that `results` were received.
  static void NotifyObservers(scoped_refptr<ObserverList> observer_list,
                              const QueryResultMap& results);

  SEQUENCE_CHECKER(sequence_checker_);

  // Parameters passed from the QueryBuilder.
  std::unique_ptr<internal::QueryParams> params_
      GUARDED_BY_CONTEXT(sequence_checker_);

  scoped_refptr<ObserverList> observer_list_ =
      base::MakeRefCounted<ObserverList>();

  // A base::RepeatingTimer used to schedule repeating queries, and some
  // tracking data to throttle QueryOnce() calls so they don't interfere. This
  // is in a pointer because ScopedResourceUsageQuery is movable but
  // RepeatingTimer isn't.
  // TODO(crbug.com/40926264): Manage timing centrally in QueryScheduler.
  std::unique_ptr<ThrottledTimer> throttled_timer_
      GUARDED_BY_CONTEXT(sequence_checker_);
};

// Convenience alias for a ScopedObservation that observes a
// ScopedResourceUsageQuery.
using ScopedQueryObservation =
    base::ScopedObservation<ScopedResourceUsageQuery, QueryResultObserver>;

// Creates a query to request resource usage measurements on a schedule.
//
// Use CreateScopedQuery() to return an object that makes repeated measurements
// as long as it's in scope, or QueryOnce() to take a single measurement. Before
// calling either of these, the query must specify:
//
//  * At least one resource type to measure, with AddResourceType().
//  * At least one resource context to attribute the measurements to, with
//    AddResourceContext() or AddAllContextsOfType().
//
// Example usage:
//
//   // To invoke `callback` with the CPU usage of all processes.
//   QueryBuilder()
//       .AddAllContextsOfType<ProcessContext>()
//       .AddResourceType(ResourceType::kCPUTime)
//       .QueryOnce(callback);
//
// QueryBuilder is move-only to prevent accidentally copying large state. Use
// Clone() to make an explicit copy.
class QueryBuilder {
 public:
  QueryBuilder();
  ~QueryBuilder();

  // Move-only.
  QueryBuilder(QueryBuilder&&);
  QueryBuilder& operator=(QueryBuilder&&);
  QueryBuilder(const QueryBuilder&) = delete;
  QueryBuilder& operator=(const QueryBuilder&) = delete;

  // Adds `context` to the list of resource contexts to query.
  QueryBuilder& AddResourceContext(const ResourceContext& context);

  // Adds all resource contexts of type ContextType to the list of resource
  // contexts to query. Whenever the query causes a resource measurement, all
  // resource contexts of the given type that exist at that moment will be
  // measured.
  template <typename ContextType>
    requires(internal::kIsVariantAlternative<ContextType, ResourceContext>)
  QueryBuilder& AddAllContextsOfType() {
    return AddAllContextsWithTypeId(
        internal::ResourceContextTypeId::ForType<ContextType>());
  }

  // Add `type` to the lists of resources to query.
  QueryBuilder& AddResourceType(ResourceType resource_type);

  // Returns a scoped object that will repeatedly run the query and notify
  // observers with the results. Once this is called the QueryBuilder becomes
  // invalid.
  ScopedResourceUsageQuery CreateScopedQuery();

  // Runs the query and calls `callback` with the result. Once this is called
  // the QueryBuilder becomes invalid. This must be called on the UI thread,
  // which is also the thread `callback` will be invoked on.
  // TODO(crbug.com/40926264): This takes an immediate measurement. Implement
  // more notification schedules.
  void QueryOnce(base::OnceCallback<void(const QueryResultMap&)> callback);

  // Makes a copy of the QueryBuilder to use as a base for similar queries.
  QueryBuilder Clone() const;

  // Restricted implementation methods:

  // Gives tests access to validate the implementation.
  internal::QueryParams* GetParamsForTesting() const;

 private:
  // Private constructor for Clone().
  explicit QueryBuilder(std::unique_ptr<internal::QueryParams> params);

  // Implementation of AddAllContextsOfType().
  QueryBuilder& AddAllContextsWithTypeId(
      internal::ResourceContextTypeId type_id);

  // Asserts all members needed for QueryOnce() or CreateScopedQuery() are set.
  void ValidateQuery() const;

  SEQUENCE_CHECKER(sequence_checker_);

  // Parameters built up by the builder.
  std::unique_ptr<internal::QueryParams> params_
      GUARDED_BY_CONTEXT(sequence_checker_);
};

}  // namespace resource_attribution

#endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_RESOURCE_ATTRIBUTION_QUERIES_H_