1 // Copyright 2020 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/tracing/perfetto_platform.h" 6 7 #include "base/strings/strcat.h" 8 #include "base/strings/string_number_conversions.h" 9 #include "base/task/deferred_sequenced_task_runner.h" 10 #include "base/task/task_traits.h" 11 #include "base/task/thread_pool.h" 12 #include "base/trace_event/trace_event.h" 13 #include "base/tracing/perfetto_task_runner.h" 14 #include "base/tracing_buildflags.h" 15 #include "build/build_config.h" 16 17 #if BUILDFLAG(IS_ANDROID) 18 #include "base/android/build_info.h" 19 #endif // BUILDFLAG(IS_ANDROID) 20 21 #if !BUILDFLAG(IS_NACL) 22 #include "third_party/perfetto/include/perfetto/ext/base/thread_task_runner.h" 23 #endif 24 25 namespace base { 26 namespace tracing { 27 28 namespace { 29 constexpr char kProcessNamePrefix[] = "org.chromium-"; 30 } // namespace 31 PerfettoPlatform(TaskRunnerType task_runner_type)32PerfettoPlatform::PerfettoPlatform(TaskRunnerType task_runner_type) 33 : task_runner_type_(task_runner_type), 34 deferred_task_runner_(new DeferredSequencedTaskRunner()), 35 thread_local_object_([](void* object) { 36 delete static_cast<ThreadLocalObject*>(object); 37 }) {} 38 39 PerfettoPlatform::~PerfettoPlatform() = default; 40 StartTaskRunner(scoped_refptr<SequencedTaskRunner> task_runner)41void PerfettoPlatform::StartTaskRunner( 42 scoped_refptr<SequencedTaskRunner> task_runner) { 43 DCHECK_EQ(task_runner_type_, TaskRunnerType::kThreadPool); 44 DCHECK(!did_start_task_runner_); 45 deferred_task_runner_->StartWithTaskRunner(task_runner); 46 did_start_task_runner_ = true; 47 } 48 task_runner() const49SequencedTaskRunner* PerfettoPlatform::task_runner() const { 50 return deferred_task_runner_.get(); 51 } 52 53 PerfettoPlatform::ThreadLocalObject* GetOrCreateThreadLocalObject()54PerfettoPlatform::GetOrCreateThreadLocalObject() { 55 auto* object = static_cast<ThreadLocalObject*>(thread_local_object_.Get()); 56 if (!object) { 57 object = ThreadLocalObject::CreateInstance().release(); 58 thread_local_object_.Set(object); 59 } 60 return object; 61 } 62 CreateTaskRunner(const CreateTaskRunnerArgs &)63std::unique_ptr<perfetto::base::TaskRunner> PerfettoPlatform::CreateTaskRunner( 64 const CreateTaskRunnerArgs&) { 65 switch (task_runner_type_) { 66 case TaskRunnerType::kBuiltin: 67 #if !BUILDFLAG(IS_NACL) 68 return std::make_unique<perfetto::base::ThreadTaskRunner>( 69 perfetto::base::ThreadTaskRunner::CreateAndStart()); 70 #else 71 DCHECK(false); 72 return nullptr; 73 #endif 74 case TaskRunnerType::kThreadPool: 75 // We can't create a real task runner yet because the ThreadPool may not 76 // be initialized. Instead, we point Perfetto to a buffering task runner 77 // which will become active as soon as the thread pool is up (see 78 // StartTaskRunner). 79 return std::make_unique<PerfettoTaskRunner>(deferred_task_runner_); 80 } 81 } 82 83 // This method is used by the SDK to determine the producer name. 84 // Note that we override the producer name for the mojo backend in ProducerHost, 85 // and thus this only affects the producer name for the system backend. GetCurrentProcessName()86std::string PerfettoPlatform::GetCurrentProcessName() { 87 const char* host_package_name = nullptr; 88 #if BUILDFLAG(IS_ANDROID) 89 host_package_name = android::BuildInfo::GetInstance()->host_package_name(); 90 #endif // BUILDFLAG(IS_ANDROID) 91 92 // On Android we want to include if this is webview inside of an app or 93 // Android Chrome. To aid this we add the host_package_name to differentiate 94 // the various apps and sources. 95 std::string process_name; 96 if (host_package_name) { 97 process_name = StrCat( 98 {kProcessNamePrefix, host_package_name, "-", 99 NumberToString(trace_event::TraceLog::GetInstance()->process_id())}); 100 } else { 101 process_name = StrCat( 102 {kProcessNamePrefix, 103 NumberToString(trace_event::TraceLog::GetInstance()->process_id())}); 104 } 105 return process_name; 106 } 107 GetCurrentThreadId()108perfetto::base::PlatformThreadId PerfettoPlatform::GetCurrentThreadId() { 109 return base::PlatformThread::CurrentId(); 110 } 111 112 } // namespace tracing 113 } // namespace base 114