• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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 #include <stddef.h>
6 
7 #include "base/trace_event/trace_event_impl.h"
8 #include "base/trace_event/trace_log.h"
9 #include "base/trace_event/trace_sampling_thread.h"
10 
11 namespace base {
12 namespace trace_event {
13 
14 class TraceBucketData {
15  public:
16   TraceBucketData(base::subtle::AtomicWord* bucket,
17                   const char* name,
18                   TraceSampleCallback callback);
19   ~TraceBucketData();
20 
21   TRACE_EVENT_API_ATOMIC_WORD* bucket;
22   const char* bucket_name;
23   TraceSampleCallback callback;
24 };
25 
TraceSamplingThread()26 TraceSamplingThread::TraceSamplingThread()
27     : thread_running_(false), waitable_event_for_testing_(false, false) {}
28 
~TraceSamplingThread()29 TraceSamplingThread::~TraceSamplingThread() {}
30 
ThreadMain()31 void TraceSamplingThread::ThreadMain() {
32   PlatformThread::SetName("Sampling Thread");
33   thread_running_ = true;
34   const int kSamplingFrequencyMicroseconds = 1000;
35   while (!cancellation_flag_.IsSet()) {
36     PlatformThread::Sleep(
37         TimeDelta::FromMicroseconds(kSamplingFrequencyMicroseconds));
38     GetSamples();
39     waitable_event_for_testing_.Signal();
40   }
41 }
42 
43 // static
DefaultSamplingCallback(TraceBucketData * bucket_data)44 void TraceSamplingThread::DefaultSamplingCallback(
45     TraceBucketData* bucket_data) {
46   TRACE_EVENT_API_ATOMIC_WORD category_and_name =
47       TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket);
48   if (!category_and_name)
49     return;
50   const char* const combined =
51       reinterpret_cast<const char* const>(category_and_name);
52   const char* category_group;
53   const char* name;
54   ExtractCategoryAndName(combined, &category_group, &name);
55   TRACE_EVENT_API_ADD_TRACE_EVENT(
56       TRACE_EVENT_PHASE_SAMPLE,
57       TraceLog::GetCategoryGroupEnabled(category_group), name, 0, 0, NULL, NULL,
58       NULL, NULL, 0);
59 }
60 
GetSamples()61 void TraceSamplingThread::GetSamples() {
62   for (size_t i = 0; i < sample_buckets_.size(); ++i) {
63     TraceBucketData* bucket_data = &sample_buckets_[i];
64     bucket_data->callback.Run(bucket_data);
65   }
66 }
67 
RegisterSampleBucket(TRACE_EVENT_API_ATOMIC_WORD * bucket,const char * const name,TraceSampleCallback callback)68 void TraceSamplingThread::RegisterSampleBucket(
69     TRACE_EVENT_API_ATOMIC_WORD* bucket,
70     const char* const name,
71     TraceSampleCallback callback) {
72   // Access to sample_buckets_ doesn't cause races with the sampling thread
73   // that uses the sample_buckets_, because it is guaranteed that
74   // RegisterSampleBucket is called before the sampling thread is created.
75   DCHECK(!thread_running_);
76   sample_buckets_.push_back(TraceBucketData(bucket, name, callback));
77 }
78 
79 // static
ExtractCategoryAndName(const char * combined,const char ** category,const char ** name)80 void TraceSamplingThread::ExtractCategoryAndName(const char* combined,
81                                                  const char** category,
82                                                  const char** name) {
83   *category = combined;
84   *name = &combined[strlen(combined) + 1];
85 }
86 
Stop()87 void TraceSamplingThread::Stop() {
88   cancellation_flag_.Set();
89 }
90 
WaitSamplingEventForTesting()91 void TraceSamplingThread::WaitSamplingEventForTesting() {
92   waitable_event_for_testing_.Wait();
93 }
94 
TraceBucketData(base::subtle::AtomicWord * bucket,const char * name,TraceSampleCallback callback)95 TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket,
96                                  const char* name,
97                                  TraceSampleCallback callback)
98     : bucket(bucket), bucket_name(name), callback(callback) {}
99 
~TraceBucketData()100 TraceBucketData::~TraceBucketData() {}
101 
102 }  // namespace trace_event
103 }  // namespace base
104