blob: 52b127705d012d05ee8346a1e8faf0252002b300 [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
Primiano Tucci53589332017-12-19 11:31:13 +010025#include "perfetto/base/utils.h"
Primiano Tucci42e2de12017-12-07 16:46:04 +000026#include "perfetto/base/weak_ptr.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000027#include "perfetto/tracing/core/basic_types.h"
Primiano Tucci53589332017-12-19 11:31:13 +010028#include "perfetto/tracing/core/data_source_descriptor.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000029#include "perfetto/tracing/core/service.h"
Primiano Tucci53589332017-12-19 11:31:13 +010030#include "perfetto/tracing/core/shared_memory_abi.h"
31#include "src/tracing/core/id_allocator.h"
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000032
33namespace perfetto {
34
35namespace base {
36class TaskRunner;
37} // namespace base
38
Primiano Tucci42e2de12017-12-07 16:46:04 +000039class Consumer;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000040class DataSourceConfig;
41class Producer;
42class SharedMemory;
Primiano Tucci42e2de12017-12-07 16:46:04 +000043class TraceConfig;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000044
45// The tracing service business logic.
46class ServiceImpl : public Service {
47 public:
48 // The implementation behind the service endpoint exposed to each producer.
49 class ProducerEndpointImpl : public Service::ProducerEndpoint {
50 public:
51 ProducerEndpointImpl(ProducerID,
52 ServiceImpl*,
53 base::TaskRunner*,
54 Producer*,
55 std::unique_ptr<SharedMemory>);
56 ~ProducerEndpointImpl() override;
57
58 Producer* producer() const { return producer_; }
59
60 // Service::ProducerEndpoint implementation.
61 void RegisterDataSource(const DataSourceDescriptor&,
62 RegisterDataSourceCallback) override;
63 void UnregisterDataSource(DataSourceID) override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000064 void NotifySharedMemoryUpdate(
65 const std::vector<uint32_t>& changed_pages) override;
Primiano Tucciaf429f92017-12-19 01:51:50 +010066 std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000067 SharedMemory* shared_memory() const override;
68
69 private:
70 ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
71 ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
72
73 ProducerID const id_;
74 ServiceImpl* const service_;
75 base::TaskRunner* const task_runner_;
76 Producer* producer_;
77 std::unique_ptr<SharedMemory> shared_memory_;
Primiano Tucci53589332017-12-19 11:31:13 +010078 SharedMemoryABI shmem_abi_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +000079 DataSourceID last_data_source_id_ = 0;
80 };
81
Primiano Tucci42e2de12017-12-07 16:46:04 +000082 // The implementation behind the service endpoint exposed to each consumer.
83 class ConsumerEndpointImpl : public Service::ConsumerEndpoint {
84 public:
85 ConsumerEndpointImpl(ServiceImpl*, base::TaskRunner*, Consumer*);
86 ~ConsumerEndpointImpl() override;
87
88 Consumer* consumer() const { return consumer_; }
89 base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr();
90
91 // Service::ConsumerEndpoint implementation.
92 void EnableTracing(const TraceConfig&) override;
93 void DisableTracing() override;
94 void ReadBuffers() override;
95 void FreeBuffers() override;
96
97 private:
98 ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
99 ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
100
101 ServiceImpl* const service_;
102 Consumer* const consumer_;
103 base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;
104 };
105
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000106 explicit ServiceImpl(std::unique_ptr<SharedMemory::Factory>,
107 base::TaskRunner*);
108 ~ServiceImpl() override;
109
Primiano Tucci42e2de12017-12-07 16:46:04 +0000110 // Called by ProducerEndpointImpl.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000111 void DisconnectProducer(ProducerID);
Primiano Tucci53589332017-12-19 11:31:13 +0100112 void RegisterDataSource(ProducerID,
113 DataSourceID,
114 const DataSourceDescriptor&);
115 void CopyProducerPageIntoLogBuffer(ProducerID,
116 BufferID,
117 const uint8_t*,
118 size_t);
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000119
Primiano Tucci42e2de12017-12-07 16:46:04 +0000120 // Called by ConsumerEndpointImpl.
121 void DisconnectConsumer(ConsumerEndpointImpl*);
122 void EnableTracing(ConsumerEndpointImpl*, const TraceConfig&);
123 void DisableTracing(ConsumerEndpointImpl*);
124 void ReadBuffers(ConsumerEndpointImpl*);
125 void FreeBuffers(ConsumerEndpointImpl*);
126
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000127 // Service implementation.
128 std::unique_ptr<Service::ProducerEndpoint> ConnectProducer(
129 Producer*,
130 size_t shared_buffer_size_hint_bytes = 0) override;
Primiano Tucci42e2de12017-12-07 16:46:04 +0000131
132 std::unique_ptr<Service::ConsumerEndpoint> ConnectConsumer(
133 Consumer*) override;
134
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000135 // Exposed mainly for testing.
136 size_t num_producers() const { return producers_.size(); }
137 ProducerEndpointImpl* GetProducer(ProducerID) const;
138
139 private:
Primiano Tucci53589332017-12-19 11:31:13 +0100140 struct RegisteredDataSource {
141 ProducerID producer_id;
142 DataSourceID data_source_id;
143 DataSourceDescriptor descriptor;
144 };
145
146 struct TraceBuffer {
147 // TODO(primiano): make this configurable.
148 static constexpr size_t kBufferPageSize = 4096;
149 explicit TraceBuffer(size_t size);
150 ~TraceBuffer();
151 TraceBuffer(TraceBuffer&&) noexcept;
152 TraceBuffer& operator=(TraceBuffer&&);
153
154 size_t num_pages() const { return size / kBufferPageSize; }
155
156 uint8_t* get_page(size_t page) {
157 PERFETTO_DCHECK(page < num_pages());
158 return reinterpret_cast<uint8_t*>(data.get()) + page * kBufferPageSize;
159 }
160
161 uint8_t* get_next_page() {
162 size_t cur = cur_page;
163 cur_page = cur_page == num_pages() - 1 ? 0 : cur_page + 1;
164 return get_page(cur);
165 }
166
167 size_t size;
168 size_t cur_page = 0; // Write pointer in the ring buffer.
169 std::unique_ptr<void, base::FreeDeleter> data;
170
171 // TODO(primiano): The TraceBuffer is not shared and there is no reason to
172 // use the SharedMemoryABI. This is just a a temporary workaround to reuse
173 // the convenience of SharedMemoryABI for bookkeeping of the buffer when
174 // implementing ReadBuffers().
175 std::unique_ptr<SharedMemoryABI> abi;
176 };
177
178 // Holds the state of a tracing session. A tracing session is uniquely bound
179 // a specific Consumer. Each Consumer can own one or more sessions.
180 struct TracingSession {
181 // List of data source instances that have been enabled on the various
182 // producers for this tracing session.
183 std::multimap<ProducerID, DataSourceInstanceID> data_source_instances;
184
185 // The key of this map matches the |target_buffer| in the
186 // SharedMemoryABI::ChunkHeader.
187 std::map<BufferID, TraceBuffer> trace_buffers;
188 };
189
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000190 ServiceImpl(const ServiceImpl&) = delete;
191 ServiceImpl& operator=(const ServiceImpl&) = delete;
192
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000193 base::TaskRunner* const task_runner_;
Primiano Tucci53589332017-12-19 11:31:13 +0100194 std::unique_ptr<SharedMemory::Factory> shm_factory_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000195 ProducerID last_producer_id_ = 0;
Primiano Tucci53589332017-12-19 11:31:13 +0100196 DataSourceInstanceID last_data_source_instance_id_ = 0;
197
198 // Buffer IDs are global across all consumers (because a Producer can produce
199 // data for more than one trace session, hence more than one consumer).
200 IdAllocator buffer_ids_;
201
202 std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
203
204 // TODO(primiano): There doesn't seem to be any good reason why |producers_|
205 // is a map indexed by ID and not just a set<ProducerEndpointImpl*>.
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000206 std::map<ProducerID, ProducerEndpointImpl*> producers_;
Primiano Tucci53589332017-12-19 11:31:13 +0100207
Primiano Tucci42e2de12017-12-07 16:46:04 +0000208 std::set<ConsumerEndpointImpl*> consumers_;
Primiano Tucci53589332017-12-19 11:31:13 +0100209 std::map<ConsumerEndpointImpl*, TracingSession> tracing_sessions_;
Primiano Tucci4f9b6d72017-12-05 20:59:16 +0000210};
211
212} // namespace perfetto
213
214#endif // SRC_TRACING_CORE_SERVICE_IMPL_H_