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.
5 #include "base/trace_event/trace_sampling_thread.h"
6 #include "base/trace_event/trace_event_impl.h"
7 #include "base/trace_event/trace_log.h"
10 namespace trace_event
{
12 class TraceBucketData
{
14 TraceBucketData(base::subtle::AtomicWord
* bucket
,
16 TraceSampleCallback callback
);
19 TRACE_EVENT_API_ATOMIC_WORD
* bucket
;
20 const char* bucket_name
;
21 TraceSampleCallback callback
;
24 TraceSamplingThread::TraceSamplingThread()
25 : thread_running_(false), waitable_event_for_testing_(false, false) {}
27 TraceSamplingThread::~TraceSamplingThread() {}
29 void TraceSamplingThread::ThreadMain() {
30 PlatformThread::SetName("Sampling Thread");
31 thread_running_
= true;
32 const int kSamplingFrequencyMicroseconds
= 1000;
33 while (!cancellation_flag_
.IsSet()) {
34 PlatformThread::Sleep(
35 TimeDelta::FromMicroseconds(kSamplingFrequencyMicroseconds
));
37 waitable_event_for_testing_
.Signal();
42 void TraceSamplingThread::DefaultSamplingCallback(
43 TraceBucketData
* bucket_data
) {
44 TRACE_EVENT_API_ATOMIC_WORD category_and_name
=
45 TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data
->bucket
);
46 if (!category_and_name
)
48 const char* const combined
=
49 reinterpret_cast<const char* const>(category_and_name
);
50 const char* category_group
;
52 ExtractCategoryAndName(combined
, &category_group
, &name
);
53 TRACE_EVENT_API_ADD_TRACE_EVENT(
54 TRACE_EVENT_PHASE_SAMPLE
,
55 TraceLog::GetCategoryGroupEnabled(category_group
), name
, 0, 0, NULL
, NULL
,
59 void TraceSamplingThread::GetSamples() {
60 for (size_t i
= 0; i
< sample_buckets_
.size(); ++i
) {
61 TraceBucketData
* bucket_data
= &sample_buckets_
[i
];
62 bucket_data
->callback
.Run(bucket_data
);
66 void TraceSamplingThread::RegisterSampleBucket(
67 TRACE_EVENT_API_ATOMIC_WORD
* bucket
,
68 const char* const name
,
69 TraceSampleCallback callback
) {
70 // Access to sample_buckets_ doesn't cause races with the sampling thread
71 // that uses the sample_buckets_, because it is guaranteed that
72 // RegisterSampleBucket is called before the sampling thread is created.
73 DCHECK(!thread_running_
);
74 sample_buckets_
.push_back(TraceBucketData(bucket
, name
, callback
));
78 void TraceSamplingThread::ExtractCategoryAndName(const char* combined
,
79 const char** category
,
82 *name
= &combined
[strlen(combined
) + 1];
85 void TraceSamplingThread::Stop() {
86 cancellation_flag_
.Set();
89 void TraceSamplingThread::WaitSamplingEventForTesting() {
90 waitable_event_for_testing_
.Wait();
93 TraceBucketData::TraceBucketData(base::subtle::AtomicWord
* bucket
,
95 TraceSampleCallback callback
)
96 : bucket(bucket
), bucket_name(name
), callback(callback
) {}
98 TraceBucketData::~TraceBucketData() {}
100 } // namespace trace_event