Add initial Tracing Service implementation
The code still has lot of rough edges and TODOs, but
is in a good state to test integration with other system
components and cover CTS tests.
Bug: 70284518
Change-Id: Id6ac73426750cc4002d4e5bca65a66f4684c116b
diff --git a/src/tracing/core/service_impl.h b/src/tracing/core/service_impl.h
index 91db0fb..52b1277 100644
--- a/src/tracing/core/service_impl.h
+++ b/src/tracing/core/service_impl.h
@@ -22,9 +22,13 @@
#include <memory>
#include <set>
+#include "perfetto/base/utils.h"
#include "perfetto/base/weak_ptr.h"
#include "perfetto/tracing/core/basic_types.h"
+#include "perfetto/tracing/core/data_source_descriptor.h"
#include "perfetto/tracing/core/service.h"
+#include "perfetto/tracing/core/shared_memory_abi.h"
+#include "src/tracing/core/id_allocator.h"
namespace perfetto {
@@ -71,6 +75,7 @@
base::TaskRunner* const task_runner_;
Producer* producer_;
std::unique_ptr<SharedMemory> shared_memory_;
+ SharedMemoryABI shmem_abi_;
DataSourceID last_data_source_id_ = 0;
};
@@ -104,6 +109,13 @@
// Called by ProducerEndpointImpl.
void DisconnectProducer(ProducerID);
+ void RegisterDataSource(ProducerID,
+ DataSourceID,
+ const DataSourceDescriptor&);
+ void CopyProducerPageIntoLogBuffer(ProducerID,
+ BufferID,
+ const uint8_t*,
+ size_t);
// Called by ConsumerEndpointImpl.
void DisconnectConsumer(ConsumerEndpointImpl*);
@@ -125,14 +137,76 @@
ProducerEndpointImpl* GetProducer(ProducerID) const;
private:
+ struct RegisteredDataSource {
+ ProducerID producer_id;
+ DataSourceID data_source_id;
+ DataSourceDescriptor descriptor;
+ };
+
+ struct TraceBuffer {
+ // TODO(primiano): make this configurable.
+ static constexpr size_t kBufferPageSize = 4096;
+ explicit TraceBuffer(size_t size);
+ ~TraceBuffer();
+ TraceBuffer(TraceBuffer&&) noexcept;
+ TraceBuffer& operator=(TraceBuffer&&);
+
+ size_t num_pages() const { return size / kBufferPageSize; }
+
+ uint8_t* get_page(size_t page) {
+ PERFETTO_DCHECK(page < num_pages());
+ return reinterpret_cast<uint8_t*>(data.get()) + page * kBufferPageSize;
+ }
+
+ uint8_t* get_next_page() {
+ size_t cur = cur_page;
+ cur_page = cur_page == num_pages() - 1 ? 0 : cur_page + 1;
+ return get_page(cur);
+ }
+
+ size_t size;
+ size_t cur_page = 0; // Write pointer in the ring buffer.
+ std::unique_ptr<void, base::FreeDeleter> data;
+
+ // TODO(primiano): The TraceBuffer is not shared and there is no reason to
+ // use the SharedMemoryABI. This is just a a temporary workaround to reuse
+ // the convenience of SharedMemoryABI for bookkeeping of the buffer when
+ // implementing ReadBuffers().
+ std::unique_ptr<SharedMemoryABI> abi;
+ };
+
+ // Holds the state of a tracing session. A tracing session is uniquely bound
+ // a specific Consumer. Each Consumer can own one or more sessions.
+ struct TracingSession {
+ // List of data source instances that have been enabled on the various
+ // producers for this tracing session.
+ std::multimap<ProducerID, DataSourceInstanceID> data_source_instances;
+
+ // The key of this map matches the |target_buffer| in the
+ // SharedMemoryABI::ChunkHeader.
+ std::map<BufferID, TraceBuffer> trace_buffers;
+ };
+
ServiceImpl(const ServiceImpl&) = delete;
ServiceImpl& operator=(const ServiceImpl&) = delete;
- std::unique_ptr<SharedMemory::Factory> shm_factory_;
base::TaskRunner* const task_runner_;
+ std::unique_ptr<SharedMemory::Factory> shm_factory_;
ProducerID last_producer_id_ = 0;
+ DataSourceInstanceID last_data_source_instance_id_ = 0;
+
+ // Buffer IDs are global across all consumers (because a Producer can produce
+ // data for more than one trace session, hence more than one consumer).
+ IdAllocator buffer_ids_;
+
+ std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
+
+ // TODO(primiano): There doesn't seem to be any good reason why |producers_|
+ // is a map indexed by ID and not just a set<ProducerEndpointImpl*>.
std::map<ProducerID, ProducerEndpointImpl*> producers_;
+
std::set<ConsumerEndpointImpl*> consumers_;
+ std::map<ConsumerEndpointImpl*, TracingSession> tracing_sessions_;
};
} // namespace perfetto