• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/profiler/sample_metadata.h"
6 
7 #include "base/metrics/metrics_hashes.h"
8 #include "base/no_destructor.h"
9 #include "base/profiler/stack_sampling_profiler.h"
10 #include "base/threading/thread_local.h"
11 #include "third_party/abseil-cpp/absl/types/optional.h"
12 
13 namespace base {
14 
15 namespace {
16 
GetPlatformThreadIdForScope(SampleMetadataScope scope)17 absl::optional<PlatformThreadId> GetPlatformThreadIdForScope(
18     SampleMetadataScope scope) {
19   if (scope == SampleMetadataScope::kProcess)
20     return absl::nullopt;
21   return PlatformThread::CurrentId();
22 }
23 
24 }  // namespace
25 
SampleMetadata(StringPiece name,SampleMetadataScope scope)26 SampleMetadata::SampleMetadata(StringPiece name, SampleMetadataScope scope)
27     : name_hash_(HashMetricName(name)), scope_(scope) {}
28 
Set(int64_t value)29 void SampleMetadata::Set(int64_t value) {
30   GetSampleMetadataRecorder()->Set(name_hash_, absl::nullopt,
31                                    GetPlatformThreadIdForScope(scope_), value);
32 }
33 
Set(int64_t key,int64_t value)34 void SampleMetadata::Set(int64_t key, int64_t value) {
35   GetSampleMetadataRecorder()->Set(name_hash_, key,
36                                    GetPlatformThreadIdForScope(scope_), value);
37 }
38 
Remove()39 void SampleMetadata::Remove() {
40   GetSampleMetadataRecorder()->Remove(name_hash_, absl::nullopt,
41                                       GetPlatformThreadIdForScope(scope_));
42 }
43 
Remove(int64_t key)44 void SampleMetadata::Remove(int64_t key) {
45   GetSampleMetadataRecorder()->Remove(name_hash_, key,
46                                       GetPlatformThreadIdForScope(scope_));
47 }
48 
ScopedSampleMetadata(StringPiece name,int64_t value,SampleMetadataScope scope)49 ScopedSampleMetadata::ScopedSampleMetadata(StringPiece name,
50                                            int64_t value,
51                                            SampleMetadataScope scope)
52     : name_hash_(HashMetricName(name)),
53       thread_id_(GetPlatformThreadIdForScope(scope)) {
54   GetSampleMetadataRecorder()->Set(name_hash_, absl::nullopt, thread_id_,
55                                    value);
56 }
57 
ScopedSampleMetadata(StringPiece name,int64_t key,int64_t value,SampleMetadataScope scope)58 ScopedSampleMetadata::ScopedSampleMetadata(StringPiece name,
59                                            int64_t key,
60                                            int64_t value,
61                                            SampleMetadataScope scope)
62     : name_hash_(HashMetricName(name)),
63       key_(key),
64       thread_id_(GetPlatformThreadIdForScope(scope)) {
65   GetSampleMetadataRecorder()->Set(name_hash_, key, thread_id_, value);
66 }
67 
~ScopedSampleMetadata()68 ScopedSampleMetadata::~ScopedSampleMetadata() {
69   GetSampleMetadataRecorder()->Remove(name_hash_, key_, thread_id_);
70 }
71 
72 // This function is friended by StackSamplingProfiler so must live directly in
73 // the base namespace.
ApplyMetadataToPastSamplesImpl(TimeTicks period_start,TimeTicks period_end,uint64_t name_hash,absl::optional<int64_t> key,int64_t value,absl::optional<PlatformThreadId> thread_id)74 void ApplyMetadataToPastSamplesImpl(
75     TimeTicks period_start,
76     TimeTicks period_end,
77     uint64_t name_hash,
78     absl::optional<int64_t> key,
79     int64_t value,
80     absl::optional<PlatformThreadId> thread_id) {
81   StackSamplingProfiler::ApplyMetadataToPastSamples(
82       period_start, period_end, name_hash, key, value, thread_id);
83 }
84 
ApplyMetadataToPastSamples(TimeTicks period_start,TimeTicks period_end,StringPiece name,int64_t value,SampleMetadataScope scope)85 void ApplyMetadataToPastSamples(TimeTicks period_start,
86                                 TimeTicks period_end,
87                                 StringPiece name,
88                                 int64_t value,
89                                 SampleMetadataScope scope) {
90   return ApplyMetadataToPastSamplesImpl(
91       period_start, period_end, HashMetricName(name), absl::nullopt, value,
92       GetPlatformThreadIdForScope(scope));
93 }
94 
ApplyMetadataToPastSamples(TimeTicks period_start,TimeTicks period_end,StringPiece name,int64_t key,int64_t value,SampleMetadataScope scope)95 void ApplyMetadataToPastSamples(TimeTicks period_start,
96                                 TimeTicks period_end,
97                                 StringPiece name,
98                                 int64_t key,
99                                 int64_t value,
100                                 SampleMetadataScope scope) {
101   return ApplyMetadataToPastSamplesImpl(period_start, period_end,
102                                         HashMetricName(name), key, value,
103                                         GetPlatformThreadIdForScope(scope));
104 }
105 
AddProfileMetadataImpl(uint64_t name_hash,int64_t key,int64_t value,absl::optional<PlatformThreadId> thread_id)106 void AddProfileMetadataImpl(uint64_t name_hash,
107                             int64_t key,
108                             int64_t value,
109                             absl::optional<PlatformThreadId> thread_id) {
110   StackSamplingProfiler::AddProfileMetadata(name_hash, key, value, thread_id);
111 }
112 
AddProfileMetadata(StringPiece name,int64_t key,int64_t value,SampleMetadataScope scope)113 void AddProfileMetadata(StringPiece name,
114                         int64_t key,
115                         int64_t value,
116                         SampleMetadataScope scope) {
117   return AddProfileMetadataImpl(HashMetricName(name), key, value,
118                                 GetPlatformThreadIdForScope(scope));
119 }
120 
GetSampleMetadataRecorder()121 MetadataRecorder* GetSampleMetadataRecorder() {
122   static NoDestructor<MetadataRecorder> instance;
123   return instance.get();
124 }
125 
126 }  // namespace base
127