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