OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef COMPONENTS_TRACING_CORE_TRACE_BUFFER_WRITER_H_ |
| 6 #define COMPONENTS_TRACING_CORE_TRACE_BUFFER_WRITER_H_ |
| 7 |
| 8 #include "base/macros.h" |
| 9 #include "components/tracing/core/proto_zero_message.h" |
| 10 #include "components/tracing/core/proto_zero_message_handle.h" |
| 11 #include "components/tracing/core/scattered_stream_writer.h" |
| 12 #include "components/tracing/core/trace_ring_buffer.h" |
| 13 #include "components/tracing/tracing_export.h" |
| 14 |
| 15 namespace tracing { |
| 16 |
| 17 // TODO(primiano): in next CL the Event class will just come from the C++ |
| 18 // header generated by the ProtoZero plugin. |
| 19 namespace proto { |
| 20 class Event : public v2::ProtoZeroMessage {}; |
| 21 } |
| 22 |
| 23 namespace v2 { |
| 24 |
| 25 using TraceEventHandle = ProtoZeroMessageHandle<proto::Event>; |
| 26 |
| 27 // This class is the entry-point to add events to the TraceRingBuffer. |
| 28 // It acts as a glue layer between the protobuf classes (ProtoZeroMessage) and |
| 29 // the chunked trace ring buffer (TraceRingBuffer). This class is deliberately |
| 30 // NOT thread safe. The expected design is that each thread owns an instance of |
| 31 // TraceBufferWriter and that trace events produced on one thread are not passed |
| 32 // to other threads. |
| 33 class TRACING_EXPORT TraceBufferWriter |
| 34 : public ScatteredStreamWriter::Delegate { |
| 35 public: |
| 36 // |trace_ring_buffer| is the underlying ring buffer for taking and returning |
| 37 // chunks. |writer_id| is an identifier, unique for each instance, which is |
| 38 // appended to the header of each chunk. Its purpose is to allow the importer |
| 39 // to reconstruct the logical sequence of chunks for a given writer. Think to |
| 40 // this as a thread-id (just, in rare cases, some threads can have more than |
| 41 // one writer). |
| 42 TraceBufferWriter(TraceRingBuffer* trace_ring_buffer, uint32_t writer_id); |
| 43 ~TraceBufferWriter() override; |
| 44 |
| 45 // Adds a new event and returns a handle to it. The new event is valid (can be |
| 46 // populated) until the next call to AddEvent(). The new event is finalized |
| 47 // and fully committed to the ring buffer on the next call to AddEvent() or |
| 48 // when the returned handle goes out of scope, whichever comes first. |
| 49 TraceEventHandle AddEvent(); |
| 50 |
| 51 // ScatteredStreamWriter::Delegate implementation. |
| 52 // Called by the ProtoZeroMessage's ScatteredStreamWriter when the caller |
| 53 // tries to append a new field and the write overflows the current chunk. |
| 54 ContiguousMemoryRange GetNewBuffer() override; |
| 55 |
| 56 // Finalize the pending event (if any) and returns back all chunks to the |
| 57 // |trace_ring_buffer_|. |
| 58 void Flush(); |
| 59 |
| 60 const ScatteredStreamWriter& stream_writer() const { return stream_writer_; } |
| 61 |
| 62 uint32_t writer_id() const { return writer_id_; } |
| 63 |
| 64 private: |
| 65 void FinalizeCurrentEvent(); |
| 66 void FinalizeCurrentChunk(bool is_fragmenting_event); |
| 67 ContiguousMemoryRange AcquireNewChunk(bool event_continues_from_prev_chunk); |
| 68 uint8_t* WriteEventPreambleForNewChunk(uint8_t* begin); |
| 69 |
| 70 TraceRingBuffer* trace_ring_buffer_; |
| 71 |
| 72 // Unique id of this writer (see comment in the ctor). |
| 73 const uint32_t writer_id_; |
| 74 |
| 75 // Monotonic counter (within the scope of writer_id_) of chunks. |
| 76 uint32_t chunk_seq_id_; |
| 77 |
| 78 // The last chunk acquired from the ring buffer. nullptr before the first call |
| 79 // to AddEvent(). Each instance can own more than one chunk at any given time |
| 80 // (to deal with messages larger than a chunk). This is being tracked through |
| 81 // the singly linked list Chunk::next_in_owner_list(). |
| 82 TraceRingBuffer::Chunk* chunk_; |
| 83 |
| 84 // Used to work out how many bytes for the current |event_| lie in the current |
| 85 // |chunk_|. |
| 86 uint8_t* event_data_start_in_current_chunk_; |
| 87 |
| 88 ScatteredStreamWriter stream_writer_; |
| 89 |
| 90 // This field should be a proto::Event. However, ProtoZeroMessage subclasses |
| 91 // are stateless by design. This avoids to pull the full tree of autogenerated |
| 92 // headers for the stub classes and reduce build time. |
| 93 ProtoZeroMessage event_; |
| 94 |
| 95 DISALLOW_COPY_AND_ASSIGN(TraceBufferWriter); |
| 96 }; |
| 97 |
| 98 } // namespace v2 |
| 99 } // namespace tracing |
| 100 |
| 101 #endif // COMPONENTS_TRACING_CORE_TRACE_BUFFER_WRITER_H_ |
OLD | NEW |