OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/tracing/core/trace_buffer_writer.h" | 5 #include "components/tracing/core/trace_buffer_writer.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "components/tracing/core/proto_utils.h" | 9 #include "components/tracing/core/proto_utils.h" |
| 10 #include "components/tracing/proto/event.pbzero.h" |
10 #include "components/tracing/proto/events_chunk.pbzero.h" | 11 #include "components/tracing/proto/events_chunk.pbzero.h" |
11 | 12 |
12 namespace tracing { | 13 namespace tracing { |
13 namespace v2 { | 14 namespace v2 { |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 using ChunkProto = pbzero::tracing::proto::EventsChunk; | 18 using ChunkProto = pbzero::tracing::proto::EventsChunk; |
18 | 19 |
19 const size_t kEventPreambleSize = 1 + proto::kMessageLengthFieldSize; | 20 const size_t kEventPreambleSize = 1 + proto::kMessageLengthFieldSize; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 // starting a partial event that will fragment immediately after. | 70 // starting a partial event that will fragment immediately after. |
70 static_assert(kMinEventSize >= proto::kMessageLengthFieldSize + 1, | 71 static_assert(kMinEventSize >= proto::kMessageLengthFieldSize + 1, |
71 "kMinEventSize too small"); | 72 "kMinEventSize too small"); |
72 if (stream_writer_.bytes_available() < kMinEventSize) | 73 if (stream_writer_.bytes_available() < kMinEventSize) |
73 stream_writer_.Reset(AcquireNewChunk(false /* is_fragmenting_event */)); | 74 stream_writer_.Reset(AcquireNewChunk(false /* is_fragmenting_event */)); |
74 | 75 |
75 event_.Reset(&stream_writer_); | 76 event_.Reset(&stream_writer_); |
76 WriteEventPreambleForNewChunk( | 77 WriteEventPreambleForNewChunk( |
77 stream_writer_.ReserveBytesUnsafe(kEventPreambleSize)); | 78 stream_writer_.ReserveBytesUnsafe(kEventPreambleSize)); |
78 DCHECK_EQ(stream_writer_.write_ptr(), event_data_start_in_current_chunk_); | 79 DCHECK_EQ(stream_writer_.write_ptr(), event_data_start_in_current_chunk_); |
79 return TraceEventHandle(static_cast<::tracing::proto::Event*>(&event_)); | 80 return TraceEventHandle(static_cast<pbzero::tracing::proto::Event*>(&event_)); |
80 } | 81 } |
81 | 82 |
82 // This is invoked by the ProtoZeroMessage write methods when reaching the | 83 // This is invoked by the ProtoZeroMessage write methods when reaching the |
83 // end of the current chunk during a write. | 84 // end of the current chunk during a write. |
84 ContiguousMemoryRange TraceBufferWriter::GetNewBuffer() { | 85 ContiguousMemoryRange TraceBufferWriter::GetNewBuffer() { |
85 return AcquireNewChunk(true /* is_fragmenting_event */); | 86 return AcquireNewChunk(true /* is_fragmenting_event */); |
86 } | 87 } |
87 | 88 |
88 void TraceBufferWriter::FinalizeCurrentChunk(bool is_fragmenting_event) { | 89 void TraceBufferWriter::FinalizeCurrentChunk(bool is_fragmenting_event) { |
89 DCHECK(!is_fragmenting_event || chunk_); | 90 DCHECK(!is_fragmenting_event || chunk_); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 // Write the protobuf for the chunk header. The generated C++ stub for | 144 // Write the protobuf for the chunk header. The generated C++ stub for |
144 // events_chunk.proto cannot be used here because that would re-enter this | 145 // events_chunk.proto cannot be used here because that would re-enter this |
145 // class and make this code extremely hard to reason about. | 146 // class and make this code extremely hard to reason about. |
146 uint8_t* chunk_proto = new_chunk->payload(); | 147 uint8_t* chunk_proto = new_chunk->payload(); |
147 | 148 |
148 proto::StaticAssertSingleBytePreamble<ChunkProto::kWriterIdFieldNumber>(); | 149 proto::StaticAssertSingleBytePreamble<ChunkProto::kWriterIdFieldNumber>(); |
149 *chunk_proto++ = static_cast<uint8_t>( | 150 *chunk_proto++ = static_cast<uint8_t>( |
150 proto::MakeTagVarInt(ChunkProto::kWriterIdFieldNumber)); | 151 proto::MakeTagVarInt(ChunkProto::kWriterIdFieldNumber)); |
151 chunk_proto = proto::WriteVarInt(writer_id_, chunk_proto); | 152 chunk_proto = proto::WriteVarInt(writer_id_, chunk_proto); |
152 | 153 |
153 proto::StaticAssertSingleBytePreamble< | 154 proto::StaticAssertSingleBytePreamble<ChunkProto::kSeqIdFieldNumber>(); |
154 ChunkProto::kSeqIdFieldNumber>(); | 155 *chunk_proto++ = |
155 *chunk_proto++ = static_cast<uint8_t>( | 156 static_cast<uint8_t>(proto::MakeTagVarInt(ChunkProto::kSeqIdFieldNumber)); |
156 proto::MakeTagVarInt(ChunkProto::kSeqIdFieldNumber)); | |
157 chunk_proto = proto::WriteVarInt(chunk_seq_id_, chunk_proto); | 157 chunk_proto = proto::WriteVarInt(chunk_seq_id_, chunk_proto); |
158 | 158 |
159 if (is_fragmenting_event) { | 159 if (is_fragmenting_event) { |
160 proto::StaticAssertSingleBytePreamble< | 160 proto::StaticAssertSingleBytePreamble< |
161 ChunkProto::kFirstEventContinuesFromPrevChunkFieldNumber>(); | 161 ChunkProto::kFirstEventContinuesFromPrevChunkFieldNumber>(); |
162 *chunk_proto++ = static_cast<uint8_t>(proto::MakeTagVarInt( | 162 *chunk_proto++ = static_cast<uint8_t>(proto::MakeTagVarInt( |
163 ChunkProto::kFirstEventContinuesFromPrevChunkFieldNumber)); | 163 ChunkProto::kFirstEventContinuesFromPrevChunkFieldNumber)); |
164 *chunk_proto++ = 1; // = true. | 164 *chunk_proto++ = 1; // = true. |
165 } | 165 } |
166 | 166 |
(...skipping 20 matching lines...) Expand all Loading... |
187 proto::StaticAssertSingleBytePreamble<ChunkProto::kEventsFieldNumber>(); | 187 proto::StaticAssertSingleBytePreamble<ChunkProto::kEventsFieldNumber>(); |
188 *begin++ = static_cast<uint8_t>( | 188 *begin++ = static_cast<uint8_t>( |
189 proto::MakeTagLengthDelimited(ChunkProto::kEventsFieldNumber)); | 189 proto::MakeTagLengthDelimited(ChunkProto::kEventsFieldNumber)); |
190 ContiguousMemoryRange range = {begin, end}; | 190 ContiguousMemoryRange range = {begin, end}; |
191 event_.set_size_field(range); | 191 event_.set_size_field(range); |
192 event_data_start_in_current_chunk_ = end; | 192 event_data_start_in_current_chunk_ = end; |
193 return end; | 193 return end; |
194 } | 194 } |
195 | 195 |
196 void TraceBufferWriter::Flush() { | 196 void TraceBufferWriter::Flush() { |
| 197 if (!chunk_) |
| 198 return; |
197 FinalizeCurrentEvent(); | 199 FinalizeCurrentEvent(); |
198 FinalizeCurrentChunk(false /* is_fragmenting_event */); | 200 FinalizeCurrentChunk(false /* is_fragmenting_event */); |
199 trace_ring_buffer_->ReturnChunk(chunk_); | 201 trace_ring_buffer_->ReturnChunk(chunk_); |
200 chunk_ = nullptr; | 202 chunk_ = nullptr; |
201 } | 203 } |
202 | 204 |
203 } // namespace v2 | 205 } // namespace v2 |
204 } // namespace tracing | 206 } // namespace tracing |
OLD | NEW |