sample_metadata.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2019 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. #ifndef BASE_PROFILER_SAMPLE_METADATA_H_
  5. #define BASE_PROFILER_SAMPLE_METADATA_H_
  6. #include "base/optional.h"
  7. #include "base/profiler/metadata_recorder.h"
  8. #include "base/strings/string_piece.h"
  9. // -----------------------------------------------------------------------------
  10. // Usage documentation
  11. // -----------------------------------------------------------------------------
  12. //
  13. // Overview:
  14. // These functions provide a means to control the metadata attached to samples
  15. // collected by the stack sampling profiler. Metadata state is shared between
  16. // all threads within a process.
  17. //
  18. // Any samples collected by the sampling profiler will include the active
  19. // metadata. This enables us to later analyze targeted subsets of samples
  20. // (e.g. those collected during paint or layout).
  21. //
  22. // For example:
  23. //
  24. // void DidStartLoad() {
  25. // is_loading_metadata_.Set(1);
  26. // }
  27. //
  28. // void DidFinishLoad() {
  29. // is_loading_metadata_.Remove();
  30. // }
  31. //
  32. // base::SampleMetadata is_loading_metadata_;
  33. //
  34. // Alternatively, ScopedSampleMetadata can be used to ensure that the metadata
  35. // is removed correctly.
  36. //
  37. // For example:
  38. //
  39. // void DoExpensiveWork() {
  40. // base::ScopedSampleMetadata metadata("xyz", 1);
  41. // if (...) {
  42. // ...
  43. // if (...) {
  44. // ...
  45. // return;
  46. // }
  47. // }
  48. // ...
  49. // }
  50. namespace base {
  51. class BASE_EXPORT SampleMetadata {
  52. public:
  53. // Set the metadata value associated with |name|.
  54. explicit SampleMetadata(StringPiece name);
  55. SampleMetadata(const SampleMetadata&) = default;
  56. ~SampleMetadata() = default;
  57. SampleMetadata& operator=(const SampleMetadata&) = delete;
  58. // Set the metadata value associated with |name| in the process-global stack
  59. // sampling profiler metadata, overwriting any previous value set for that
  60. // |name|.
  61. void Set(int64_t value);
  62. // Set the metadata value associated with the pair (|name|, |key|) in the
  63. // process-global stack sampling profiler metadata, overwriting any previous
  64. // value set for that (|name|, |key|) pair. This constructor allows the
  65. // metadata to be associated with an additional user-defined key. One might
  66. // supply a key based on the frame id, for example, to distinguish execution
  67. // in service of scrolling between different frames. Prefer the previous
  68. // function if no user-defined metadata is required. Note: values specified
  69. // for a name and key are stored separately from values specified with only a
  70. // name.
  71. void Set(int64_t key, int64_t value);
  72. // Removes the metadata item with the specified name from the process-global
  73. // stack sampling profiler metadata.
  74. //
  75. // If such an item doesn't exist, this has no effect.
  76. void Remove();
  77. // Removes the metadata item with the specified (|name|, |key|) pair from the
  78. // process-global stack sampling profiler metadata. This function does not
  79. // alter values set with the name |name| but no key.
  80. //
  81. // If such an item doesn't exist, this has no effect.
  82. void Remove(int64_t key);
  83. private:
  84. const uint64_t name_hash_;
  85. };
  86. class BASE_EXPORT ScopedSampleMetadata {
  87. public:
  88. // Set the metadata value associated with |name|.
  89. ScopedSampleMetadata(StringPiece name, int64_t value);
  90. // Set the metadata value associated with the pair (|name|, |key|). This
  91. // constructor allows the metadata to be associated with an additional
  92. // user-defined key. One might supply a key based on the frame id, for
  93. // example, to distinguish execution in service of scrolling between different
  94. // frames. Prefer the previous constructor if no user-defined metadata is
  95. // required. Note: values specified for a name and key are stored separately
  96. // from values specified with only a name.
  97. ScopedSampleMetadata(StringPiece name, int64_t key, int64_t value);
  98. ScopedSampleMetadata(const ScopedSampleMetadata&) = delete;
  99. ~ScopedSampleMetadata();
  100. ScopedSampleMetadata& operator=(const ScopedSampleMetadata&) = delete;
  101. private:
  102. const uint64_t name_hash_;
  103. Optional<int64_t> key_;
  104. };
  105. // Applies the specified metadata to samples already recorded between
  106. // |period_start| and |period_end| in all thread's active profiles, subject to
  107. // the condition that the profile fully encompasses the period and the profile
  108. // has not already completed. The condition ensures that the metadata is applied
  109. // only if all execution during its scope was seen in the profile. This avoids
  110. // biasng the samples towards the 'middle' of the execution seen during the
  111. // metadata scope (i.e. because the start or end of execution was missed), at
  112. // the cost of missing execution that are longer than the profiling period, or
  113. // extend before or after it. |period_end| must be <= TimeTicks::Now().
  114. BASE_EXPORT void ApplyMetadataToPastSamples(TimeTicks period_start,
  115. TimeTicks period_end,
  116. StringPiece name,
  117. int64_t value);
  118. BASE_EXPORT void ApplyMetadataToPastSamples(TimeTicks period_start,
  119. TimeTicks period_end,
  120. StringPiece name,
  121. int64_t key,
  122. int64_t value);
  123. // Returns the process-global metadata recorder instance used for tracking
  124. // sampling profiler metadata.
  125. //
  126. // This function should not be called by non-profiler related code.
  127. BASE_EXPORT MetadataRecorder* GetSampleMetadataRecorder();
  128. } // namespace base
  129. #endif // BASE_PROFILER_SAMPLE_METADATA_H_