Home | History | Annotate | Download | only in trace_event
      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 
     26 TraceSamplingThread::TraceSamplingThread()
     27     : thread_running_(false), waitable_event_for_testing_(false, false) {}
     28 
     29 TraceSamplingThread::~TraceSamplingThread() {}
     30 
     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
     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 
     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 
     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
     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 
     87 void TraceSamplingThread::Stop() {
     88   cancellation_flag_.Set();
     89 }
     90 
     91 void TraceSamplingThread::WaitSamplingEventForTesting() {
     92   waitable_event_for_testing_.Wait();
     93 }
     94 
     95 TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket,
     96                                  const char* name,
     97                                  TraceSampleCallback callback)
     98     : bucket(bucket), bucket_name(name), callback(callback) {}
     99 
    100 TraceBucketData::~TraceBucketData() {}
    101 
    102 }  // namespace trace_event
    103 }  // namespace base
    104