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_TRACE_WRITER_IMPL_H_
     18 #define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
     19 
     20 #include "perfetto/protozero/message_handle.h"
     21 #include "perfetto/protozero/scattered_stream_writer.h"
     22 #include "perfetto/tracing/core/basic_types.h"
     23 #include "perfetto/tracing/core/shared_memory_abi.h"
     24 #include "perfetto/tracing/core/trace_writer.h"
     25 #include "src/tracing/core/patch_list.h"
     26 
     27 namespace perfetto {
     28 
     29 class SharedMemoryArbiterImpl;
     30 
     31 // See //include/perfetto/tracing/core/trace_writer.h for docs.
     32 class TraceWriterImpl : public TraceWriter,
     33                         public protozero::ScatteredStreamWriter::Delegate {
     34  public:
     35   // TracePacketHandle is defined in trace_writer.h
     36   TraceWriterImpl(SharedMemoryArbiterImpl*, WriterID, BufferID);
     37   ~TraceWriterImpl() override;
     38 
     39   // TraceWriter implementation. See documentation in trace_writer.h.
     40   TracePacketHandle NewTracePacket() override;
     41   void Flush(std::function<void()> callback = {}) override;
     42   WriterID writer_id() const override;
     43 
     44  private:
     45   TraceWriterImpl(const TraceWriterImpl&) = delete;
     46   TraceWriterImpl& operator=(const TraceWriterImpl&) = delete;
     47 
     48   // ScatteredStreamWriter::Delegate implementation.
     49   protozero::ContiguousMemoryRange GetNewBuffer() override;
     50 
     51   // The per-producer arbiter that coordinates access to the shared memory
     52   // buffer from several threads.
     53   SharedMemoryArbiterImpl* const shmem_arbiter_;
     54 
     55   // ID of the current writer.
     56   const WriterID id_;
     57 
     58   // This is just copied back into the chunk header.
     59   // See comments in data_source_config.proto for |target_buffer|.
     60   const BufferID target_buffer_;
     61 
     62   // Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
     63   // this allows the Service to reconstruct the linear sequence of packets.
     64   uint16_t next_chunk_id_ = 0;
     65 
     66   // The chunk we are holding onto (if any).
     67   SharedMemoryABI::Chunk cur_chunk_;
     68 
     69   // Passed to protozero message to write directly into |cur_chunk_|. It
     70   // keeps track of the write pointer. It calls us back (GetNewBuffer()) when
     71   // |cur_chunk_| is filled.
     72   protozero::ScatteredStreamWriter protobuf_stream_writer_;
     73 
     74   // The packet returned via NewTracePacket(). Its owned by this class,
     75   // TracePacketHandle has just a pointer to it.
     76   std::unique_ptr<protos::pbzero::TracePacket> cur_packet_;
     77 
     78   // The start address of |cur_packet_| within |cur_chunk_|. Used to figure out
     79   // fragments sizes when a TracePacket write is interrupted by GetNewBuffer().
     80   uint8_t* cur_fragment_start_ = nullptr;
     81 
     82   // true if we received a call to GetNewBuffer() after NewTracePacket(),
     83   // false if GetNewBuffer() happened during NewTracePacket() prologue, while
     84   // starting the TracePacket header.
     85   bool fragmenting_packet_ = false;
     86 
     87   // When a packet is fragmented across different chunks, the |size_field| of
     88   // the outstanding nested protobuf messages is redirected onto Patch entries
     89   // in this list at the time the Chunk is returned (because at that point we
     90   // have to release the ownership of the current Chunk). This list will be
     91   // later sent out-of-band to the tracing service, who will patch the required
     92   // chunks, if they are still around.
     93   PatchList patch_list_;
     94 };
     95 
     96 }  // namespace perfetto
     97 
     98 #endif  // SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
     99