blob: 046e983bfb90a922e41d2d2b56e8db8a8f8b13b5 [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 Tucci2ffd1a52018-03-27 01:01:30 +010026#include "perfetto/base/logging.h"
Primiano Tuccibbaa58c2017-12-20 13:48:20 +010027#include "perfetto/base/page_allocator.h"
Sami Kyostilafbccb3c2018-03-21 14:00:47 +000028#include "perfetto/base/time.h"
Primiano Tucci42e2de12017-12-07 16:46:04 +000029#include "perfetto/base/weak_ptr.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000030#include "perfetto/tracing/core/basic_types.h"
Primiano Tucciecf9e4a2018-03-14 14:51:58 +000031#include "perfetto/tracing/core/commit_data_request.h"
Primiano Tucci53589332017-12-19 11:31:13 +010032#include "perfetto/tracing/core/data_source_descriptor.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000033#include "perfetto/tracing/core/service.h"
Primiano Tucci53589332017-12-19 11:31:13 +010034#include "perfetto/tracing/core/shared_memory_abi.h"
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -080035#include "perfetto/tracing/core/trace_config.h"
Primiano Tucci53589332017-12-19 11:31:13 +010036#include "src/tracing/core/id_allocator.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000037
38namespace perfetto {
39
40namespace base {
41class TaskRunner;
42} // namespace base
43
Primiano Tucci42e2de12017-12-07 16:46:04 +000044class Consumer;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000045class DataSourceConfig;
46class Producer;
47class SharedMemory;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +010048class SharedMemoryArbiterImpl;
Hector Dearman6214c8f2018-03-27 16:16:22 +010049class TraceBuffer;
Primiano Tucci42e2de12017-12-07 16:46:04 +000050class TraceConfig;
Sami Kyostilafbccb3c2018-03-21 14:00:47 +000051class TracePacket;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000052
53// The tracing service business logic.
54class ServiceImpl : public Service {
55 public:
Primiano Tucci1a1951d2018-04-04 21:08:16 +020056 static constexpr size_t kDefaultShmSize = 256 * 1024ul;
Primiano Tuccie7ca7c62018-04-07 08:28:03 +020057 static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020058
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000059 // The implementation behind the service endpoint exposed to each producer.
60 class ProducerEndpointImpl : public Service::ProducerEndpoint {
61 public:
62 ProducerEndpointImpl(ProducerID,
Sami Kyostila32e0b542018-02-14 08:55:43 +000063 uid_t uid,
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000064 ServiceImpl*,
65 base::TaskRunner*,
Isabelle Taylor86262cb2018-03-27 16:00:54 +010066 Producer*,
67 const std::string& producer_name);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000068 ~ProducerEndpointImpl() override;
69
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000070 // Service::ProducerEndpoint implementation.
Primiano Tucci9daa4832018-03-28 23:28:17 +010071 void RegisterDataSource(const DataSourceDescriptor&) override;
72 void UnregisterDataSource(const std::string& name) override;
Primiano Tucci3e69ed92018-03-14 14:52:29 +000073 void CommitData(const CommitDataRequest&, CommitDataCallback) override;
Isabelle Taylor69faa902018-03-21 15:42:03 +000074 void SetSharedMemory(std::unique_ptr<SharedMemory>);
75
Primiano Tucciaf429f92017-12-19 01:51:50 +010076 std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override;
Primiano Tuccidca727d2018-04-04 11:31:55 +020077 void OnTracingSetup();
Primiano Tuccid52e6272018-04-06 19:06:53 +020078 void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
Primiano Tuccidca727d2018-04-04 11:31:55 +020079 void CreateDataSourceInstance(DataSourceInstanceID,
80 const DataSourceConfig&);
Primiano Tuccid52e6272018-04-06 19:06:53 +020081 void NotifyFlushComplete(FlushRequestID) override;
Primiano Tuccidca727d2018-04-04 11:31:55 +020082 void TearDownDataSource(DataSourceInstanceID);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000083 SharedMemory* shared_memory() const override;
Isabelle Taylor69faa902018-03-21 15:42:03 +000084 size_t shared_buffer_page_size_kb() const override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000085
86 private:
Primiano Tucci20d441d2018-01-16 09:25:51 +000087 friend class ServiceImpl;
Primiano Tucci1a1951d2018-04-04 21:08:16 +020088 friend class ServiceImplTest;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000089 ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
90 ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
Primiano Tuccidca727d2018-04-04 11:31:55 +020091 SharedMemoryArbiterImpl* GetOrCreateShmemArbiter();
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000092
93 ProducerID const id_;
Sami Kyostila32e0b542018-02-14 08:55:43 +000094 const uid_t uid_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000095 ServiceImpl* const service_;
96 base::TaskRunner* const task_runner_;
97 Producer* producer_;
98 std::unique_ptr<SharedMemory> shared_memory_;
Isabelle Taylor69faa902018-03-21 15:42:03 +000099 size_t shared_buffer_page_size_kb_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100100 SharedMemoryABI shmem_abi_;
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200101 size_t shmem_size_hint_bytes_ = 0;
Isabelle Taylor86262cb2018-03-27 16:00:54 +0100102 const std::string name_;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100103
104 // This is used only in in-process configurations (mostly tests).
105 std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
Florian Mayercd08ec62018-01-31 17:49:25 +0000106 PERFETTO_THREAD_CHECKER(thread_checker_)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200107 base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_; // Keep last.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000108 };
109
Primiano Tucci42e2de12017-12-07 16:46:04 +0000110 // The implementation behind the service endpoint exposed to each consumer.
111 class ConsumerEndpointImpl : public Service::ConsumerEndpoint {
112 public:
113 ConsumerEndpointImpl(ServiceImpl*, base::TaskRunner*, Consumer*);
114 ~ConsumerEndpointImpl() override;
115
Primiano Tuccidca727d2018-04-04 11:31:55 +0200116 void NotifyOnTracingDisabled();
Primiano Tucci42e2de12017-12-07 16:46:04 +0000117 base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr();
118
119 // Service::ConsumerEndpoint implementation.
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100120 void EnableTracing(const TraceConfig&, base::ScopedFile) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000121 void DisableTracing() override;
122 void ReadBuffers() override;
123 void FreeBuffers() override;
Primiano Tuccid52e6272018-04-06 19:06:53 +0200124 void Flush(int timeout_ms, FlushCallback) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000125
126 private:
Primiano Tucci20d441d2018-01-16 09:25:51 +0000127 friend class ServiceImpl;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000128 ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
129 ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
130
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100131 base::TaskRunner* const task_runner_;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000132 ServiceImpl* const service_;
133 Consumer* const consumer_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000134 TracingSessionID tracing_session_id_ = 0;
Florian Mayercd08ec62018-01-31 17:49:25 +0000135 PERFETTO_THREAD_CHECKER(thread_checker_)
Primiano Tuccidca727d2018-04-04 11:31:55 +0200136 base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_; // Keep last.
Primiano Tucci42e2de12017-12-07 16:46:04 +0000137 };
138
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000139 explicit ServiceImpl(std::unique_ptr<SharedMemory::Factory>,
140 base::TaskRunner*);
141 ~ServiceImpl() override;
142
Primiano Tucci42e2de12017-12-07 16:46:04 +0000143 // Called by ProducerEndpointImpl.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000144 void DisconnectProducer(ProducerID);
Primiano Tucci9daa4832018-03-28 23:28:17 +0100145 void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
146 void UnregisterDataSource(ProducerID, const std::string& name);
Primiano Tucci53589332017-12-19 11:31:13 +0100147 void CopyProducerPageIntoLogBuffer(ProducerID,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000148 uid_t,
149 WriterID,
150 ChunkID,
Primiano Tucci53589332017-12-19 11:31:13 +0100151 BufferID,
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000152 uint16_t num_fragments,
153 uint8_t chunk_flags,
154 const uint8_t* src,
155 size_t size);
156 void ApplyChunkPatches(ProducerID,
157 const std::vector<CommitDataRequest::ChunkToPatch>&);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200158 void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000159
Primiano Tucci42e2de12017-12-07 16:46:04 +0000160 // Called by ConsumerEndpointImpl.
161 void DisconnectConsumer(ConsumerEndpointImpl*);
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100162 bool EnableTracing(ConsumerEndpointImpl*,
163 const TraceConfig&,
164 base::ScopedFile);
Primiano Tucci20d441d2018-01-16 09:25:51 +0000165 void DisableTracing(TracingSessionID);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200166 void Flush(TracingSessionID tsid,
167 int timeout_ms,
168 ConsumerEndpoint::FlushCallback);
169 void FlushAndDisableTracing(TracingSessionID);
Primiano Tucci20d441d2018-01-16 09:25:51 +0000170 void ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
171 void FreeBuffers(TracingSessionID);
Primiano Tucci42e2de12017-12-07 16:46:04 +0000172
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000173 // Service implementation.
174 std::unique_ptr<Service::ProducerEndpoint> ConnectProducer(
175 Producer*,
Sami Kyostila32e0b542018-02-14 08:55:43 +0000176 uid_t uid,
Isabelle Taylor86262cb2018-03-27 16:00:54 +0100177 const std::string& producer_name,
Isabelle Taylor69faa902018-03-21 15:42:03 +0000178 size_t shared_memory_size_hint_bytes = 0) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000179
180 std::unique_ptr<Service::ConsumerEndpoint> ConnectConsumer(
181 Consumer*) override;
182
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000183 // Exposed mainly for testing.
184 size_t num_producers() const { return producers_.size(); }
185 ProducerEndpointImpl* GetProducer(ProducerID) const;
186
187 private:
Primiano Tucci1a1951d2018-04-04 21:08:16 +0200188 friend class ServiceImplTest;
Primiano Tucci081d46a2018-02-28 11:09:43 +0000189
Primiano Tucci53589332017-12-19 11:31:13 +0100190 struct RegisteredDataSource {
191 ProducerID producer_id;
Primiano Tucci53589332017-12-19 11:31:13 +0100192 DataSourceDescriptor descriptor;
193 };
194
Sami Kyostila06487a22018-02-27 13:48:38 +0000195 // Represents an active data source for a tracing session.
196 struct DataSourceInstance {
197 DataSourceInstanceID instance_id;
Primiano Tucci9daa4832018-03-28 23:28:17 +0100198 std::string data_source_name;
Sami Kyostila06487a22018-02-27 13:48:38 +0000199 };
200
Primiano Tuccid52e6272018-04-06 19:06:53 +0200201 struct PendingFlush {
202 std::set<ProducerID> producers;
203 ConsumerEndpoint::FlushCallback callback;
204 explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
205 };
206
Primiano Tucci53589332017-12-19 11:31:13 +0100207 // Holds the state of a tracing session. A tracing session is uniquely bound
208 // a specific Consumer. Each Consumer can own one or more sessions.
209 struct TracingSession {
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100210 TracingSession(ConsumerEndpointImpl*, const TraceConfig&);
Primiano Tucci20d441d2018-01-16 09:25:51 +0000211
212 size_t num_buffers() const { return buffers_index.size(); }
213
Sami Kyostila01c45f02018-03-29 15:43:10 +0100214 int delay_to_next_write_period_ms() const {
215 PERFETTO_DCHECK(write_period_ms > 0);
216 return write_period_ms -
217 (base::GetWallTimeMs().count() % write_period_ms);
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100218 }
219
220 // The consumer that started the session.
221 ConsumerEndpointImpl* const consumer;
222
Primiano Tucci20d441d2018-01-16 09:25:51 +0000223 // The original trace config provided by the Consumer when calling
224 // EnableTracing().
225 const TraceConfig config;
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -0800226
Primiano Tucci53589332017-12-19 11:31:13 +0100227 // List of data source instances that have been enabled on the various
228 // producers for this tracing session.
Sami Kyostila06487a22018-02-27 13:48:38 +0000229 std::multimap<ProducerID, DataSourceInstance> data_source_instances;
Primiano Tucci53589332017-12-19 11:31:13 +0100230
Primiano Tuccid52e6272018-04-06 19:06:53 +0200231 // For each Flush(N) request, keeps track of the set of producers for which
232 // we are still awaiting a NotifyFlushComplete(N) ack.
233 std::map<FlushRequestID, PendingFlush> pending_flushes;
234
Primiano Tucci20d441d2018-01-16 09:25:51 +0000235 // Maps a per-trace-session buffer index into the corresponding global
236 // BufferID (shared namespace amongst all consumers). This vector has as
237 // many entries as |config.buffers_size()|.
238 std::vector<BufferID> buffers_index;
Sami Kyostilafbccb3c2018-03-21 14:00:47 +0000239
240 // When the last clock snapshot was emitted into the output stream.
241 base::TimeMillis last_clock_snapshot = {};
Sami Kyostila200bd2e2018-03-26 12:24:10 +0100242
243 // Whether we mirrored the trace config back to the trace output yet.
244 bool did_emit_config = false;
Primiano Tucci2ffd1a52018-03-27 01:01:30 +0100245
246 bool tracing_enabled = false;
247
248 // This is set when the Consumer calls sets |write_into_file| == true in the
249 // TraceConfig. In this case this represents the file we should stream the
250 // trace packets into, rather than returning it to the consumer via
251 // OnTraceData().
252 base::ScopedFile write_into_file;
253 int write_period_ms = 0;
254 size_t max_file_size_bytes = 0;
255 size_t bytes_written_into_file = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100256 };
257
Primiano Tucci20d441d2018-01-16 09:25:51 +0000258 ServiceImpl(const ServiceImpl&) = delete;
259 ServiceImpl& operator=(const ServiceImpl&) = delete;
260
Sami Kyostila06487a22018-02-27 13:48:38 +0000261 void CreateDataSourceInstance(const TraceConfig::DataSource&,
Isabelle Taylor86262cb2018-03-27 16:00:54 +0100262 const TraceConfig::ProducerConfig&,
Sami Kyostila06487a22018-02-27 13:48:38 +0000263 const RegisteredDataSource&,
264 TracingSession*);
Oystein Eftevaag1269b4a2018-01-10 16:29:38 -0800265
Primiano Tucci081d46a2018-02-28 11:09:43 +0000266 // Returns the next available ProducerID that is not in |producers_|.
267 ProducerID GetNextProducerID();
268
Primiano Tucci20d441d2018-01-16 09:25:51 +0000269 // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
270 // session doesn't exists.
271 TracingSession* GetTracingSession(TracingSessionID);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000272
Lalit Maganti485faff2018-03-06 11:51:35 +0000273 // Update the memory guard rail by using the latest information from the
274 // shared memory and trace buffers.
275 void UpdateMemoryGuardrail();
276
Sami Kyostilafbccb3c2018-03-21 14:00:47 +0000277 void MaybeSnapshotClocks(TracingSession*, std::vector<TracePacket>*);
Sami Kyostila200bd2e2018-03-26 12:24:10 +0100278 void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
Primiano Tuccid52e6272018-04-06 19:06:53 +0200279 void OnFlushTimeout(TracingSessionID, FlushRequestID);
Hector Dearman6214c8f2018-03-27 16:16:22 +0100280 TraceBuffer* GetBufferByID(BufferID);
Primiano Tucciecf9e4a2018-03-14 14:51:58 +0000281
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000282 base::TaskRunner* const task_runner_;
Primiano Tucci53589332017-12-19 11:31:13 +0100283 std::unique_ptr<SharedMemory::Factory> shm_factory_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000284 ProducerID last_producer_id_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100285 DataSourceInstanceID last_data_source_instance_id_ = 0;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000286 TracingSessionID last_tracing_session_id_ = 0;
Primiano Tuccid52e6272018-04-06 19:06:53 +0200287 FlushRequestID last_flush_request_id_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100288
289 // Buffer IDs are global across all consumers (because a Producer can produce
290 // data for more than one trace session, hence more than one consumer).
Primiano Tucci20d441d2018-01-16 09:25:51 +0000291 IdAllocator<BufferID> buffer_ids_;
Primiano Tucci53589332017-12-19 11:31:13 +0100292
293 std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000294 std::map<ProducerID, ProducerEndpointImpl*> producers_;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000295 std::set<ConsumerEndpointImpl*> consumers_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000296 std::map<TracingSessionID, TracingSession> tracing_sessions_;
Hector Dearman6214c8f2018-03-27 16:16:22 +0100297 std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
Primiano Tucci20d441d2018-01-16 09:25:51 +0000298
Florian Mayer61c55482018-03-06 14:43:54 +0000299 bool lockdown_mode_ = false;
300
Florian Mayercd08ec62018-01-31 17:49:25 +0000301 PERFETTO_THREAD_CHECKER(thread_checker_)
302
Primiano Tucci20d441d2018-01-16 09:25:51 +0000303 base::WeakPtrFactory<ServiceImpl> weak_ptr_factory_; // Keep at the end.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000304};
305
306} // namespace perfetto
307
308#endif // SRC_TRACING_CORE_SERVICE_IMPL_H_