blob: 15968773e606266167998d9e5f9d38fe64739e25 [file] [log] [blame]
Primiano Tucci4f9b6d72017-12-05 20:59:16 +00001/*
2 * Copyright (C) 2017 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#ifndef SRC_TRACING_CORE_SERVICE_IMPL_H_
18#define SRC_TRACING_CORE_SERVICE_IMPL_H_
19
20#include <functional>
21#include <map>
22#include <memory>
Primiano Tucci42e2de12017-12-07 16:46:04 +000023#include <set>
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000024
Sami Kyostila32e0b542018-02-14 08:55:43 +000025#include "gtest/gtest_prod.h"
Primiano Tuccibbaa58c2017-12-20 13:48:20 +010026#include "perfetto/base/page_allocator.h"
Sami Kyostilafbccb3c2018-03-21 14:00:47 +000027#include "perfetto/base/time.h"
Primiano Tucci42e2de12017-12-07 16:46:04 +000028#include "perfetto/base/weak_ptr.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000029#include "perfetto/tracing/core/basic_types.h"
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000030#include "perfetto/tracing/core/commit_data_request.h"
Primiano Tucci53589332017-12-19 11:31:13 +010031#include "perfetto/tracing/core/data_source_descriptor.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000032#include "perfetto/tracing/core/service.h"
Primiano Tucci53589332017-12-19 11:31:13 +010033#include "perfetto/tracing/core/shared_memory_abi.h"
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -080034#include "perfetto/tracing/core/trace_config.h"
Primiano Tucci53589332017-12-19 11:31:13 +010035#include "src/tracing/core/id_allocator.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000036
37namespace perfetto {
38
39namespace base {
40class TaskRunner;
41} // namespace base
42
Primiano Tucci42e2de12017-12-07 16:46:04 +000043class Consumer;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000044class DataSourceConfig;
45class Producer;
46class SharedMemory;
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000047class TraceBuffez;
Primiano Tucci42e2de12017-12-07 16:46:04 +000048class TraceConfig;
Sami Kyostilafbccb3c2018-03-21 14:00:47 +000049class TracePacket;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000050
51// The tracing service business logic.
52class ServiceImpl : public Service {
53 public:
54 // The implementation behind the service endpoint exposed to each producer.
55 class ProducerEndpointImpl : public Service::ProducerEndpoint {
56 public:
57 ProducerEndpointImpl(ProducerID,
Sami Kyostila32e0b542018-02-14 08:55:43 +000058 uid_t uid,
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000059 ServiceImpl*,
60 base::TaskRunner*,
Isabelle Taylor69faa902018-03-21 15:42:03 +000061 Producer*);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000062 ~ProducerEndpointImpl() override;
63
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000064 // Service::ProducerEndpoint implementation.
65 void RegisterDataSource(const DataSourceDescriptor&,
66 RegisterDataSourceCallback) override;
67 void UnregisterDataSource(DataSourceID) override;
Primiano Tucci3e69ed92018-03-14 14:52:29 +000068 void CommitData(const CommitDataRequest&, CommitDataCallback) override;
Isabelle Taylor69faa902018-03-21 15:42:03 +000069 void SetSharedMemory(std::unique_ptr<SharedMemory>);
70
Primiano Tucciaf429f92017-12-19 01:51:50 +010071 std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000072 SharedMemory* shared_memory() const override;
Isabelle Taylor69faa902018-03-21 15:42:03 +000073 size_t shared_buffer_page_size_kb() const override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000074
75 private:
Primiano Tucci20d441d2018-01-16 09:25:51 +000076 friend class ServiceImpl;
Sami Kyostila32e0b542018-02-14 08:55:43 +000077 FRIEND_TEST(ServiceImplTest, RegisterAndUnregister);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000078 ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
79 ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
80
81 ProducerID const id_;
Sami Kyostila32e0b542018-02-14 08:55:43 +000082 const uid_t uid_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000083 ServiceImpl* const service_;
84 base::TaskRunner* const task_runner_;
85 Producer* producer_;
86 std::unique_ptr<SharedMemory> shared_memory_;
Isabelle Taylor69faa902018-03-21 15:42:03 +000087 size_t shared_buffer_page_size_kb_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +010088 SharedMemoryABI shmem_abi_;
Isabelle Taylor69faa902018-03-21 15:42:03 +000089 size_t shared_memory_size_hint_bytes_ = 0;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000090 DataSourceID last_data_source_id_ = 0;
Florian Mayercd08ec62018-01-31 17:49:25 +000091 PERFETTO_THREAD_CHECKER(thread_checker_)
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000092 };
93
Primiano Tucci42e2de12017-12-07 16:46:04 +000094 // The implementation behind the service endpoint exposed to each consumer.
95 class ConsumerEndpointImpl : public Service::ConsumerEndpoint {
96 public:
97 ConsumerEndpointImpl(ServiceImpl*, base::TaskRunner*, Consumer*);
98 ~ConsumerEndpointImpl() override;
99
Primiano Tucci42e2de12017-12-07 16:46:04 +0000100 base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr();
101
102 // Service::ConsumerEndpoint implementation.
103 void EnableTracing(const TraceConfig&) override;
104 void DisableTracing() override;
105 void ReadBuffers() override;
106 void FreeBuffers() override;
107
108 private:
Primiano Tucci20d441d2018-01-16 09:25:51 +0000109 friend class ServiceImpl;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000110 ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
111 ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
112
113 ServiceImpl* const service_;
114 Consumer* const consumer_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000115 TracingSessionID tracing_session_id_ = 0;
Florian Mayercd08ec62018-01-31 17:49:25 +0000116
117 PERFETTO_THREAD_CHECKER(thread_checker_)
118
Primiano Tucci42e2de12017-12-07 16:46:04 +0000119 base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;
120 };
121
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000122 explicit ServiceImpl(std::unique_ptr<SharedMemory::Factory>,
123 base::TaskRunner*);
124 ~ServiceImpl() override;
125
Primiano Tucci42e2de12017-12-07 16:46:04 +0000126 // Called by ProducerEndpointImpl.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000127 void DisconnectProducer(ProducerID);
Primiano Tucci53589332017-12-19 11:31:13 +0100128 void RegisterDataSource(ProducerID,
129 DataSourceID,
130 const DataSourceDescriptor&);
Sami Kyostila06487a22018-02-27 13:48:38 +0000131 void UnregisterDataSource(ProducerID, DataSourceID);
Primiano Tucci53589332017-12-19 11:31:13 +0100132 void CopyProducerPageIntoLogBuffer(ProducerID,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000133 uid_t,
134 WriterID,
135 ChunkID,
Primiano Tucci53589332017-12-19 11:31:13 +0100136 BufferID,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000137 uint16_t num_fragments,
138 uint8_t chunk_flags,
139 const uint8_t* src,
140 size_t size);
141 void ApplyChunkPatches(ProducerID,
142 const std::vector<CommitDataRequest::ChunkToPatch>&);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000143
Primiano Tucci42e2de12017-12-07 16:46:04 +0000144 // Called by ConsumerEndpointImpl.
145 void DisconnectConsumer(ConsumerEndpointImpl*);
146 void EnableTracing(ConsumerEndpointImpl*, const TraceConfig&);
Primiano Tucci20d441d2018-01-16 09:25:51 +0000147 void DisableTracing(TracingSessionID);
148 void ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
149 void FreeBuffers(TracingSessionID);
Primiano Tucci42e2de12017-12-07 16:46:04 +0000150
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000151 // Service implementation.
152 std::unique_ptr<Service::ProducerEndpoint> ConnectProducer(
153 Producer*,
Sami Kyostila32e0b542018-02-14 08:55:43 +0000154 uid_t uid,
Isabelle Taylor69faa902018-03-21 15:42:03 +0000155 size_t shared_memory_size_hint_bytes = 0) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000156
157 std::unique_ptr<Service::ConsumerEndpoint> ConnectConsumer(
158 Consumer*) override;
159
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000160 // Exposed mainly for testing.
161 size_t num_producers() const { return producers_.size(); }
162 ProducerEndpointImpl* GetProducer(ProducerID) const;
163
164 private:
Primiano Tucci081d46a2018-02-28 11:09:43 +0000165 FRIEND_TEST(ServiceImplTest, ProducerIDWrapping);
166
Primiano Tucci53589332017-12-19 11:31:13 +0100167 struct RegisteredDataSource {
168 ProducerID producer_id;
169 DataSourceID data_source_id;
170 DataSourceDescriptor descriptor;
171 };
172
Sami Kyostila06487a22018-02-27 13:48:38 +0000173 // Represents an active data source for a tracing session.
174 struct DataSourceInstance {
175 DataSourceInstanceID instance_id;
176 DataSourceID data_source_id;
177 };
178
Primiano Tucci53589332017-12-19 11:31:13 +0100179 // Holds the state of a tracing session. A tracing session is uniquely bound
180 // a specific Consumer. Each Consumer can own one or more sessions.
181 struct TracingSession {
Primiano Tucci20d441d2018-01-16 09:25:51 +0000182 explicit TracingSession(const TraceConfig&);
183
184 size_t num_buffers() const { return buffers_index.size(); }
185
Isabelle Taylor69faa902018-03-21 15:42:03 +0000186 // Retrieves the page size from the trace config.
187 size_t GetDesiredPageSizeKb();
188
189 // Retrieves the SHM size from the trace config.
190 size_t GetDesiredShmSizeKb();
191
Primiano Tucci20d441d2018-01-16 09:25:51 +0000192 // The original trace config provided by the Consumer when calling
193 // EnableTracing().
194 const TraceConfig config;
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -0800195
Primiano Tucci53589332017-12-19 11:31:13 +0100196 // List of data source instances that have been enabled on the various
197 // producers for this tracing session.
Sami Kyostila06487a22018-02-27 13:48:38 +0000198 std::multimap<ProducerID, DataSourceInstance> data_source_instances;
Primiano Tucci53589332017-12-19 11:31:13 +0100199
Primiano Tucci20d441d2018-01-16 09:25:51 +0000200 // Maps a per-trace-session buffer index into the corresponding global
201 // BufferID (shared namespace amongst all consumers). This vector has as
202 // many entries as |config.buffers_size()|.
203 std::vector<BufferID> buffers_index;
Sami Kyostilafbccb3c2018-03-21 14:00:47 +0000204
205 // When the last clock snapshot was emitted into the output stream.
206 base::TimeMillis last_clock_snapshot = {};
Primiano Tucci53589332017-12-19 11:31:13 +0100207 };
208
Primiano Tucci20d441d2018-01-16 09:25:51 +0000209 ServiceImpl(const ServiceImpl&) = delete;
210 ServiceImpl& operator=(const ServiceImpl&) = delete;
211
Sami Kyostila06487a22018-02-27 13:48:38 +0000212 void CreateDataSourceInstance(const TraceConfig::DataSource&,
213 const RegisteredDataSource&,
214 TracingSession*);
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -0800215
Primiano Tucci081d46a2018-02-28 11:09:43 +0000216 // Returns the next available ProducerID that is not in |producers_|.
217 ProducerID GetNextProducerID();
218
Primiano Tucci20d441d2018-01-16 09:25:51 +0000219 // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
220 // session doesn't exists.
221 TracingSession* GetTracingSession(TracingSessionID);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000222
Lalit Maganti485faff2018-03-06 11:51:35 +0000223 // Update the memory guard rail by using the latest information from the
224 // shared memory and trace buffers.
225 void UpdateMemoryGuardrail();
226
Sami Kyostilafbccb3c2018-03-21 14:00:47 +0000227 void MaybeSnapshotClocks(TracingSession*, std::vector<TracePacket>*);
228
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000229 TraceBuffez* GetBufferByID(BufferID);
230
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000231 base::TaskRunner* const task_runner_;
Primiano Tucci53589332017-12-19 11:31:13 +0100232 std::unique_ptr<SharedMemory::Factory> shm_factory_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000233 ProducerID last_producer_id_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100234 DataSourceInstanceID last_data_source_instance_id_ = 0;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000235 TracingSessionID last_tracing_session_id_ = 0;
Isabelle Taylor69faa902018-03-21 15:42:03 +0000236 size_t shared_memory_size_hint_bytes_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100237
238 // Buffer IDs are global across all consumers (because a Producer can produce
239 // data for more than one trace session, hence more than one consumer).
Primiano Tucci20d441d2018-01-16 09:25:51 +0000240 IdAllocator<BufferID> buffer_ids_;
Primiano Tucci53589332017-12-19 11:31:13 +0100241
242 std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
243
244 // TODO(primiano): There doesn't seem to be any good reason why |producers_|
245 // is a map indexed by ID and not just a set<ProducerEndpointImpl*>.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000246 std::map<ProducerID, ProducerEndpointImpl*> producers_;
Primiano Tucci53589332017-12-19 11:31:13 +0100247
Primiano Tucci42e2de12017-12-07 16:46:04 +0000248 std::set<ConsumerEndpointImpl*> consumers_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000249 std::map<TracingSessionID, TracingSession> tracing_sessions_;
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000250 std::map<BufferID, std::unique_ptr<TraceBuffez>> buffers_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000251
Florian Mayer61c55482018-03-06 14:43:54 +0000252 bool lockdown_mode_ = false;
253
Florian Mayercd08ec62018-01-31 17:49:25 +0000254 PERFETTO_THREAD_CHECKER(thread_checker_)
255
Primiano Tucci20d441d2018-01-16 09:25:51 +0000256 base::WeakPtrFactory<ServiceImpl> weak_ptr_factory_; // Keep at the end.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000257};
258
259} // namespace perfetto
260
261#endif // SRC_TRACING_CORE_SERVICE_IMPL_H_