xref: /aosp_15_r20/external/perfetto/src/tracing/internal/in_process_tracing_backend.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "perfetto/tracing/internal/in_process_tracing_backend.h"
18 
19 #include "perfetto/base/logging.h"
20 #include "perfetto/base/task_runner.h"
21 #include "perfetto/ext/base/paged_memory.h"
22 #include "perfetto/ext/tracing/core/client_identity.h"
23 #include "perfetto/ext/tracing/core/shared_memory.h"
24 #include "perfetto/ext/tracing/core/tracing_service.h"
25 
26 #include "src/tracing/core/in_process_shared_memory.h"
27 
28 // TODO(primiano): When the in-process backend is used, we should never end up
29 // in a situation where the thread where the TracingService and Producer live
30 // writes a packet and hence can get into the GetNewChunk() stall.
31 // This would happen only if the API client code calls Trace() from one of the
32 // callbacks it receives (e.g. OnStart(), OnStop()). We should either cause a
33 // hard crash or ignore traces from that thread if that happens, because it
34 // will deadlock (the Service will never free up the SMB because won't ever get
35 // to run the task).
36 
37 namespace perfetto {
38 namespace internal {
39 
40 // static
GetInstance()41 TracingBackend* InProcessTracingBackend::GetInstance() {
42   static auto* instance = new InProcessTracingBackend();
43   return instance;
44 }
45 
46 InProcessTracingBackend::InProcessTracingBackend() = default;
47 InProcessTracingBackend::~InProcessTracingBackend() = default;
48 
ConnectProducer(const ConnectProducerArgs & args)49 std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
50     const ConnectProducerArgs& args) {
51   PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
52   return GetOrCreateService(args.task_runner)
53       ->ConnectProducer(args.producer, ClientIdentity(/*uid=*/0, /*pid=*/0),
54                         args.producer_name, args.shmem_size_hint_bytes,
55                         /*in_process=*/true,
56                         TracingService::ProducerSMBScrapingMode::kEnabled,
57                         args.shmem_page_size_hint_bytes);
58 }
59 
ConnectConsumer(const ConnectConsumerArgs & args)60 std::unique_ptr<ConsumerEndpoint> InProcessTracingBackend::ConnectConsumer(
61     const ConnectConsumerArgs& args) {
62   return GetOrCreateService(args.task_runner)
63       ->ConnectConsumer(args.consumer, /*uid=*/0);
64 }
65 
GetOrCreateService(base::TaskRunner * task_runner)66 TracingService* InProcessTracingBackend::GetOrCreateService(
67     base::TaskRunner* task_runner) {
68   if (!service_) {
69     std::unique_ptr<InProcessSharedMemory::Factory> shm(
70         new InProcessSharedMemory::Factory());
71     service_ = TracingService::CreateInstance(std::move(shm), task_runner);
72     service_->SetSMBScrapingEnabled(true);
73   }
74   return service_.get();
75 }
76 
77 }  // namespace internal
78 }  // namespace perfetto
79