1 /* 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 INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_H_ 18 #define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_H_ 19 20 #include <stdint.h> 21 22 #include <functional> 23 #include <memory> 24 #include <vector> 25 26 #include "perfetto/base/export.h" 27 #include "perfetto/base/scoped_file.h" 28 #include "perfetto/tracing/core/basic_types.h" 29 #include "perfetto/tracing/core/shared_memory.h" 30 31 namespace perfetto { 32 33 namespace base { 34 class TaskRunner; 35 } // namespace base 36 37 class CommitDataRequest; 38 class Consumer; 39 class DataSourceDescriptor; 40 class Producer; 41 class SharedMemoryArbiter; 42 class TraceConfig; 43 class TraceWriter; 44 45 // TODO: for the moment this assumes that all the calls happen on the same 46 // thread/sequence. Not sure this will be the case long term in Chrome. 47 48 // The API for the Producer port of the Service. 49 // Subclassed by: 50 // 1. The tracing_service_impl.cc business logic when returning it in response 51 // to the ConnectProducer() method. 52 // 2. The transport layer (e.g., src/ipc) when the producer and 53 // the service don't talk locally but via some IPC mechanism. 54 class PERFETTO_EXPORT ProducerEndpoint { 55 public: 56 virtual ~ProducerEndpoint(); 57 58 // Called by the Producer to (un)register data sources. Data sources are 59 // identified by their name (i.e. DataSourceDescriptor.name) 60 virtual void RegisterDataSource(const DataSourceDescriptor&) = 0; 61 virtual void UnregisterDataSource(const std::string& name) = 0; 62 63 // Associate the trace writer with the given |writer_id| with 64 // |target_buffer|. The service may use this information to retrieve and 65 // copy uncommitted chunks written by the trace writer into its associated 66 // buffer, e.g. when a producer process crashes or when a flush is 67 // necessary. 68 virtual void RegisterTraceWriter(uint32_t writer_id, 69 uint32_t target_buffer) = 0; 70 71 // Remove the association of the trace writer previously created via 72 // RegisterTraceWriter. 73 virtual void UnregisterTraceWriter(uint32_t writer_id) = 0; 74 75 // Called by the Producer to signal that some pages in the shared memory 76 // buffer (shared between Service and Producer) have changed. 77 // When the Producer and the Service are hosted in the same process and 78 // hence potentially live on the same task runner, This method must call 79 // TracingServiceImpl's CommitData synchronously, without any PostTask()s, 80 // if on the same thread. This is to avoid a deadlock where the Producer 81 // exhausts its SMB and stalls waiting for the service to catch up with 82 // reads, but the Service never gets to that because it lives on the same 83 // thread. 84 using CommitDataCallback = std::function<void()>; 85 virtual void CommitData(const CommitDataRequest&, 86 CommitDataCallback callback = {}) = 0; 87 88 virtual SharedMemory* shared_memory() const = 0; 89 90 // Size of shared memory buffer pages. It's always a multiple of 4K. 91 // See shared_memory_abi.h 92 virtual size_t shared_buffer_page_size_kb() const = 0; 93 94 // Creates a trace writer, which allows to create events, handling the 95 // underying shared memory buffer and signalling to the Service. This method 96 // is thread-safe but the returned object is not. A TraceWriter should be 97 // used only from a single thread, or the caller has to handle sequencing 98 // via a mutex or equivalent. This method can only be called if 99 // TracingService::ConnectProducer was called with |in_process=true|. 100 // Args: 101 // |target_buffer| is the target buffer ID where the data produced by the 102 // writer should be stored by the tracing service. This value is passed 103 // upon creation of the data source (StartDataSource()) in the 104 // DataSourceConfig.target_buffer(). 105 virtual std::unique_ptr<TraceWriter> CreateTraceWriter( 106 BufferID target_buffer) = 0; 107 108 // If TracingService::ConnectProducer is called with |in_process=true|, 109 // this returns the producer's SharedMemoryArbiter which can be used 110 // to create TraceWriters which is able to directly commit chunks 111 // without going through an IPC layer. 112 virtual SharedMemoryArbiter* GetInProcessShmemArbiter() = 0; 113 114 // Called in response to a Producer::Flush(request_id) call after all data 115 // for the flush request has been committed. 116 virtual void NotifyFlushComplete(FlushRequestID) = 0; 117 118 // Called in response to one or more Producer::StartDataSource(), 119 // if the data source registered setting the flag 120 // DataSourceDescriptor.will_notify_on_start. 121 virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0; 122 123 // Called in response to one or more Producer::StopDataSource(), 124 // if the data source registered setting the flag 125 // DataSourceDescriptor.will_notify_on_stop. 126 virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0; 127 128 // This informs the service to activate any of these triggers if any tracing 129 // session was waiting for them. 130 virtual void ActivateTriggers(const std::vector<std::string>&) = 0; 131 }; // class ProducerEndpoint. 132 133 // The API for the Consumer port of the Service. 134 // Subclassed by: 135 // 1. The tracing_service_impl.cc business logic when returning it in response 136 // to 137 // the ConnectConsumer() method. 138 // 2. The transport layer (e.g., src/ipc) when the consumer and 139 // the service don't talk locally but via some IPC mechanism. 140 class ConsumerEndpoint { 141 public: 142 virtual ~ConsumerEndpoint(); 143 144 // Enables tracing with the given TraceConfig. The ScopedFile argument is 145 // used only when TraceConfig.write_into_file == true. 146 // If TraceConfig.deferred_start == true data sources are configured via 147 // SetupDataSource() but are not started until StartTracing() is called. 148 // This is to support pre-initialization and fast triggering of traces. 149 // The ScopedFile argument is used only when TraceConfig.write_into_file 150 // == true. 151 virtual void EnableTracing(const TraceConfig&, 152 base::ScopedFile = base::ScopedFile()) = 0; 153 154 // Update the trace config of an existing tracing session; only a subset 155 // of options can be changed mid-session. Currently the only 156 // supported functionality is expanding the list of producer_name_filters() 157 // (or removing the filter entirely) for existing data sources. 158 virtual void ChangeTraceConfig(const TraceConfig&) = 0; 159 160 // Starts all data sources configured in the trace config. This is used only 161 // after calling EnableTracing() with TraceConfig.deferred_start=true. 162 // It's a no-op if called after a regular EnableTracing(), without setting 163 // deferred_start. 164 virtual void StartTracing() = 0; 165 166 virtual void DisableTracing() = 0; 167 168 // Requests all data sources to flush their data immediately and invokes the 169 // passed callback once all of them have acked the flush (in which case 170 // the callback argument |success| will be true) or |timeout_ms| are elapsed 171 // (in which case |success| will be false). 172 // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or, 173 // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is 174 // used. 175 using FlushCallback = std::function<void(bool /*success*/)>; 176 virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0; 177 178 // Tracing data will be delivered invoking Consumer::OnTraceData(). 179 virtual void ReadBuffers() = 0; 180 181 virtual void FreeBuffers() = 0; 182 183 // Will call OnDetach(). 184 virtual void Detach(const std::string& key) = 0; 185 186 // Will call OnAttach(). 187 virtual void Attach(const std::string& key) = 0; 188 189 // Will call OnTraceStats(). 190 virtual void GetTraceStats() = 0; 191 192 enum ObservableEventType : uint32_t { 193 kNone = 0, 194 kDataSourceInstances = 1 << 0 195 }; 196 197 // Start or stop observing events of selected types. |enabled_event_types| 198 // specifies the types of events to observe in a bitmask (see 199 // ObservableEventType enum). To disable observing, pass 200 // ObservableEventType::kNone. Will call OnObservableEvents() repeatedly 201 // whenever an event of an enabled ObservableEventType occurs. 202 // 203 // TODO(eseckler): Extend this to support producers & data sources. 204 virtual void ObserveEvents(uint32_t enabled_event_types) = 0; 205 }; // class ConsumerEndpoint. 206 207 // The public API of the tracing Service business logic. 208 // 209 // Exposed to: 210 // 1. The transport layer (e.g., src/unix_rpc/unix_service_host.cc), 211 // which forwards commands received from a remote producer or consumer to 212 // the actual service implementation. 213 // 2. Tests. 214 // 215 // Subclassed by: 216 // The service business logic in src/core/tracing_service_impl.cc. 217 class PERFETTO_EXPORT TracingService { 218 public: 219 using ProducerEndpoint = perfetto::ProducerEndpoint; 220 using ConsumerEndpoint = perfetto::ConsumerEndpoint; 221 222 enum class ProducerSMBScrapingMode { 223 // Use service's default setting for SMB scraping. Currently, the default 224 // mode is to disable SMB scraping, but this may change in the future. 225 kDefault, 226 227 // Enable scraping of uncommitted chunks in producers' shared memory 228 // buffers. 229 kEnabled, 230 231 // Disable scraping of uncommitted chunks in producers' shared memory 232 // buffers. 233 kDisabled 234 }; 235 236 // Implemented in src/core/tracing_service_impl.cc . 237 static std::unique_ptr<TracingService> CreateInstance( 238 std::unique_ptr<SharedMemory::Factory>, 239 base::TaskRunner*); 240 241 virtual ~TracingService(); 242 243 // Connects a Producer instance and obtains a ProducerEndpoint, which is 244 // essentially a 1:1 channel between one Producer and the Service. 245 // The caller has to guarantee that the passed Producer will be alive as long 246 // as the returned ProducerEndpoint is alive. 247 // Both the passed Prodcer and the returned ProducerEndpint must live on the 248 // same task runner of the service, specifically: 249 // 1) The Service will call Producer::* methods on the Service's task runner. 250 // 2) The Producer should call ProducerEndpoint::* methods only on the 251 // service's task runner, except for ProducerEndpoint::CreateTraceWriter(), 252 // which can be called on any thread. 253 // To disconnect just destroy the returned ProducerEndpoint object. It is safe 254 // to destroy the Producer once the Producer::OnDisconnect() has been invoked. 255 // |uid| is the trusted user id of the producer process, used by the consumers 256 // for validating the origin of trace data. 257 // |shared_memory_size_hint_bytes| is an optional hint on the size of the 258 // shared memory buffer. The service can ignore the hint (e.g., if the hint 259 // is unreasonably large). 260 // |in_process| enables the ProducerEndpoint to manage its own shared memory 261 // and enables use of |ProducerEndpoint::CreateTraceWriter|. 262 // Can return null in the unlikely event that service has too many producers 263 // connected. 264 virtual std::unique_ptr<ProducerEndpoint> ConnectProducer( 265 Producer*, 266 uid_t uid, 267 const std::string& name, 268 size_t shared_memory_size_hint_bytes = 0, 269 bool in_process = false, 270 ProducerSMBScrapingMode smb_scraping_mode = 271 ProducerSMBScrapingMode::kDefault) = 0; 272 273 // Connects a Consumer instance and obtains a ConsumerEndpoint, which is 274 // essentially a 1:1 channel between one Consumer and the Service. 275 // The caller has to guarantee that the passed Consumer will be alive as long 276 // as the returned ConsumerEndpoint is alive. 277 // To disconnect just destroy the returned ConsumerEndpoint object. It is safe 278 // to destroy the Consumer once the Consumer::OnDisconnect() has been invoked. 279 virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(Consumer*, 280 uid_t) = 0; 281 282 // Enable/disable scraping of chunks in the shared memory buffer. If enabled, 283 // the service will copy uncommitted but non-empty chunks from the SMB when 284 // flushing (e.g. to handle unresponsive producers or producers unable to 285 // flush their active chunks), on producer disconnect (e.g. to recover data 286 // from crashed producers), and after disabling a tracing session (e.g. to 287 // gather data from producers that didn't stop their data sources in time). 288 // 289 // This feature is currently used by Chrome. 290 virtual void SetSMBScrapingEnabled(bool enabled) = 0; 291 }; 292 293 } // namespace perfetto 294 295 #endif // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_H_ 296