Home | History | Annotate | Download | only in core
      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 SRC_TRACING_CORE_SERVICE_IMPL_H_
     18 #define SRC_TRACING_CORE_SERVICE_IMPL_H_
     19 
     20 #include <functional>
     21 #include <map>
     22 #include <memory>
     23 #include <set>
     24 
     25 #include "gtest/gtest_prod.h"
     26 #include "perfetto/base/logging.h"
     27 #include "perfetto/base/page_allocator.h"
     28 #include "perfetto/base/time.h"
     29 #include "perfetto/base/weak_ptr.h"
     30 #include "perfetto/tracing/core/basic_types.h"
     31 #include "perfetto/tracing/core/commit_data_request.h"
     32 #include "perfetto/tracing/core/data_source_descriptor.h"
     33 #include "perfetto/tracing/core/service.h"
     34 #include "perfetto/tracing/core/shared_memory_abi.h"
     35 #include "perfetto/tracing/core/trace_config.h"
     36 #include "src/tracing/core/id_allocator.h"
     37 
     38 namespace perfetto {
     39 
     40 namespace base {
     41 class TaskRunner;
     42 }  // namespace base
     43 
     44 class Consumer;
     45 class DataSourceConfig;
     46 class Producer;
     47 class SharedMemory;
     48 class SharedMemoryArbiterImpl;
     49 class TraceBuffer;
     50 class TraceConfig;
     51 class TracePacket;
     52 
     53 // The tracing service business logic.
     54 class ServiceImpl : public Service {
     55  public:
     56   static constexpr size_t kDefaultShmSize = 256 * 1024ul;
     57   static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
     58 
     59   // The implementation behind the service endpoint exposed to each producer.
     60   class ProducerEndpointImpl : public Service::ProducerEndpoint {
     61    public:
     62     ProducerEndpointImpl(ProducerID,
     63                          uid_t uid,
     64                          ServiceImpl*,
     65                          base::TaskRunner*,
     66                          Producer*,
     67                          const std::string& producer_name);
     68     ~ProducerEndpointImpl() override;
     69 
     70     // Service::ProducerEndpoint implementation.
     71     void RegisterDataSource(const DataSourceDescriptor&) override;
     72     void UnregisterDataSource(const std::string& name) override;
     73     void CommitData(const CommitDataRequest&, CommitDataCallback) override;
     74     void SetSharedMemory(std::unique_ptr<SharedMemory>);
     75 
     76     std::unique_ptr<TraceWriter> CreateTraceWriter(BufferID) override;
     77     void OnTracingSetup();
     78     void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
     79     void CreateDataSourceInstance(DataSourceInstanceID,
     80                                   const DataSourceConfig&);
     81     void NotifyFlushComplete(FlushRequestID) override;
     82     void TearDownDataSource(DataSourceInstanceID);
     83     SharedMemory* shared_memory() const override;
     84     size_t shared_buffer_page_size_kb() const override;
     85 
     86    private:
     87     friend class ServiceImpl;
     88     friend class ServiceImplTest;
     89     ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
     90     ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
     91     SharedMemoryArbiterImpl* GetOrCreateShmemArbiter();
     92 
     93     ProducerID const id_;
     94     const uid_t uid_;
     95     ServiceImpl* const service_;
     96     base::TaskRunner* const task_runner_;
     97     Producer* producer_;
     98     std::unique_ptr<SharedMemory> shared_memory_;
     99     size_t shared_buffer_page_size_kb_ = 0;
    100     SharedMemoryABI shmem_abi_;
    101     size_t shmem_size_hint_bytes_ = 0;
    102     const std::string name_;
    103 
    104     // This is used only in in-process configurations (mostly tests).
    105     std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
    106     PERFETTO_THREAD_CHECKER(thread_checker_)
    107     base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_;  // Keep last.
    108   };
    109 
    110   // 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 
    116     void NotifyOnTracingDisabled();
    117     base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr();
    118 
    119     // Service::ConsumerEndpoint implementation.
    120     void EnableTracing(const TraceConfig&, base::ScopedFile) override;
    121     void DisableTracing() override;
    122     void ReadBuffers() override;
    123     void FreeBuffers() override;
    124     void Flush(uint32_t timeout_ms, FlushCallback) override;
    125 
    126    private:
    127     friend class ServiceImpl;
    128     ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
    129     ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
    130 
    131     base::TaskRunner* const task_runner_;
    132     ServiceImpl* const service_;
    133     Consumer* const consumer_;
    134     TracingSessionID tracing_session_id_ = 0;
    135     PERFETTO_THREAD_CHECKER(thread_checker_)
    136     base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;  // Keep last.
    137   };
    138 
    139   explicit ServiceImpl(std::unique_ptr<SharedMemory::Factory>,
    140                        base::TaskRunner*);
    141   ~ServiceImpl() override;
    142 
    143   // Called by ProducerEndpointImpl.
    144   void DisconnectProducer(ProducerID);
    145   void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
    146   void UnregisterDataSource(ProducerID, const std::string& name);
    147   void CopyProducerPageIntoLogBuffer(ProducerID,
    148                                      uid_t,
    149                                      WriterID,
    150                                      ChunkID,
    151                                      BufferID,
    152                                      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>&);
    158   void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
    159 
    160   // Called by ConsumerEndpointImpl.
    161   void DisconnectConsumer(ConsumerEndpointImpl*);
    162   bool EnableTracing(ConsumerEndpointImpl*,
    163                      const TraceConfig&,
    164                      base::ScopedFile);
    165   void DisableTracing(TracingSessionID);
    166   void Flush(TracingSessionID tsid,
    167              uint32_t timeout_ms,
    168              ConsumerEndpoint::FlushCallback);
    169   void FlushAndDisableTracing(TracingSessionID);
    170   void ReadBuffers(TracingSessionID, ConsumerEndpointImpl*);
    171   void FreeBuffers(TracingSessionID);
    172 
    173   // Service implementation.
    174   std::unique_ptr<Service::ProducerEndpoint> ConnectProducer(
    175       Producer*,
    176       uid_t uid,
    177       const std::string& producer_name,
    178       size_t shared_memory_size_hint_bytes = 0) override;
    179 
    180   std::unique_ptr<Service::ConsumerEndpoint> ConnectConsumer(
    181       Consumer*) override;
    182 
    183   // Exposed mainly for testing.
    184   size_t num_producers() const { return producers_.size(); }
    185   ProducerEndpointImpl* GetProducer(ProducerID) const;
    186 
    187  private:
    188   friend class ServiceImplTest;
    189 
    190   struct RegisteredDataSource {
    191     ProducerID producer_id;
    192     DataSourceDescriptor descriptor;
    193   };
    194 
    195   // Represents an active data source for a tracing session.
    196   struct DataSourceInstance {
    197     DataSourceInstanceID instance_id;
    198     std::string data_source_name;
    199   };
    200 
    201   struct PendingFlush {
    202     std::set<ProducerID> producers;
    203     ConsumerEndpoint::FlushCallback callback;
    204     explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
    205   };
    206 
    207   // 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 {
    210     TracingSession(ConsumerEndpointImpl*, const TraceConfig&);
    211 
    212     size_t num_buffers() const { return buffers_index.size(); }
    213 
    214     uint32_t 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);
    218     }
    219 
    220     // The consumer that started the session.
    221     ConsumerEndpointImpl* const consumer;
    222 
    223     // The original trace config provided by the Consumer when calling
    224     // EnableTracing().
    225     const TraceConfig config;
    226 
    227     // List of data source instances that have been enabled on the various
    228     // producers for this tracing session.
    229     std::multimap<ProducerID, DataSourceInstance> data_source_instances;
    230 
    231     // 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 
    235     // 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;
    239 
    240     // When the last clock snapshot was emitted into the output stream.
    241     base::TimeMillis last_clock_snapshot = {};
    242 
    243     // When the last TraceStats snapshot was emitted into the output stream.
    244     base::TimeMillis last_stats_snapshot = {};
    245 
    246     // Whether we mirrored the trace config back to the trace output yet.
    247     bool did_emit_config = false;
    248 
    249     bool tracing_enabled = false;
    250 
    251     // This is set when the Consumer calls sets |write_into_file| == true in the
    252     // TraceConfig. In this case this represents the file we should stream the
    253     // trace packets into, rather than returning it to the consumer via
    254     // OnTraceData().
    255     base::ScopedFile write_into_file;
    256     uint32_t write_period_ms = 0;
    257     uint64_t max_file_size_bytes = 0;
    258     uint64_t bytes_written_into_file = 0;
    259   };
    260 
    261   ServiceImpl(const ServiceImpl&) = delete;
    262   ServiceImpl& operator=(const ServiceImpl&) = delete;
    263 
    264   void CreateDataSourceInstance(const TraceConfig::DataSource&,
    265                                 const TraceConfig::ProducerConfig&,
    266                                 const RegisteredDataSource&,
    267                                 TracingSession*);
    268 
    269   // Returns the next available ProducerID that is not in |producers_|.
    270   ProducerID GetNextProducerID();
    271 
    272   // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
    273   // session doesn't exists.
    274   TracingSession* GetTracingSession(TracingSessionID);
    275 
    276   // Update the memory guard rail by using the latest information from the
    277   // shared memory and trace buffers.
    278   void UpdateMemoryGuardrail();
    279 
    280   void MaybeSnapshotClocks(TracingSession*, std::vector<TracePacket>*);
    281   void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
    282   void MaybeSnapshotStats(TracingSession*, std::vector<TracePacket>*);
    283   void OnFlushTimeout(TracingSessionID, FlushRequestID);
    284   TraceBuffer* GetBufferByID(BufferID);
    285 
    286   base::TaskRunner* const task_runner_;
    287   std::unique_ptr<SharedMemory::Factory> shm_factory_;
    288   ProducerID last_producer_id_ = 0;
    289   DataSourceInstanceID last_data_source_instance_id_ = 0;
    290   TracingSessionID last_tracing_session_id_ = 0;
    291   FlushRequestID last_flush_request_id_ = 0;
    292   uid_t uid_ = 0;
    293 
    294   // Buffer IDs are global across all consumers (because a Producer can produce
    295   // data for more than one trace session, hence more than one consumer).
    296   IdAllocator<BufferID> buffer_ids_;
    297 
    298   std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
    299   std::map<ProducerID, ProducerEndpointImpl*> producers_;
    300   std::set<ConsumerEndpointImpl*> consumers_;
    301   std::map<TracingSessionID, TracingSession> tracing_sessions_;
    302   std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
    303 
    304   bool lockdown_mode_ = false;
    305 
    306   PERFETTO_THREAD_CHECKER(thread_checker_)
    307 
    308   base::WeakPtrFactory<ServiceImpl> weak_ptr_factory_;  // Keep at the end.
    309 };
    310 
    311 }  // namespace perfetto
    312 
    313 #endif  // SRC_TRACING_CORE_SERVICE_IMPL_H_
    314