5 #include "src/libplatform/tracing/trace-buffer.h" 11 TraceBufferRingBuffer::TraceBufferRingBuffer(
size_t max_chunks,
12 TraceWriter* trace_writer)
13 : max_chunks_(max_chunks) {
14 trace_writer_.reset(trace_writer);
15 chunks_.resize(max_chunks);
18 TraceObject* TraceBufferRingBuffer::AddTraceEvent(uint64_t* handle) {
19 base::MutexGuard guard(&mutex_);
20 if (is_empty_ || chunks_[chunk_index_]->IsFull()) {
21 chunk_index_ = is_empty_ ? 0 : NextChunkIndex(chunk_index_);
23 auto& chunk = chunks_[chunk_index_];
25 chunk->Reset(current_chunk_seq_++);
27 chunk.reset(
new TraceBufferChunk(current_chunk_seq_++));
30 auto& chunk = chunks_[chunk_index_];
32 TraceObject* trace_object = chunk->AddTraceEvent(&event_index);
33 *handle = MakeHandle(chunk_index_, chunk->seq(), event_index);
37 TraceObject* TraceBufferRingBuffer::GetEventByHandle(uint64_t handle) {
38 base::MutexGuard guard(&mutex_);
39 size_t chunk_index, event_index;
41 ExtractHandle(handle, &chunk_index, &chunk_seq, &event_index);
42 if (chunk_index >= chunks_.size())
return nullptr;
43 auto& chunk = chunks_[chunk_index];
44 if (!chunk || chunk->seq() != chunk_seq)
return nullptr;
45 return chunk->GetEventAt(event_index);
48 bool TraceBufferRingBuffer::Flush() {
49 base::MutexGuard guard(&mutex_);
52 for (
size_t i = NextChunkIndex(chunk_index_);;
i = NextChunkIndex(
i)) {
53 if (
auto& chunk = chunks_[
i]) {
54 for (
size_t j = 0; j < chunk->size(); ++j) {
55 trace_writer_->AppendTraceEvent(chunk->GetEventAt(j));
58 if (
i == chunk_index_)
break;
61 trace_writer_->Flush();
67 uint64_t TraceBufferRingBuffer::MakeHandle(
size_t chunk_index,
69 size_t event_index)
const {
70 return static_cast<uint64_t
>(chunk_seq) * Capacity() +
71 chunk_index * TraceBufferChunk::kChunkSize + event_index;
74 void TraceBufferRingBuffer::ExtractHandle(uint64_t handle,
size_t* chunk_index,
76 size_t* event_index)
const {
77 *chunk_seq =
static_cast<uint32_t>(handle / Capacity());
78 size_t indices = handle % Capacity();
79 *chunk_index = indices / TraceBufferChunk::kChunkSize;
80 *event_index = indices % TraceBufferChunk::kChunkSize;
83 size_t TraceBufferRingBuffer::NextChunkIndex(
size_t index)
const {
84 if (++index >= max_chunks_) index = 0;
88 TraceBufferChunk::TraceBufferChunk(
uint32_t seq) : seq_(seq) {}
90 void TraceBufferChunk::Reset(
uint32_t new_seq) {
95 TraceObject* TraceBufferChunk::AddTraceEvent(
size_t* event_index) {
96 *event_index = next_free_++;
97 return &chunk_[*event_index];
100 TraceBuffer* TraceBuffer::CreateTraceBufferRingBuffer(
101 size_t max_chunks, TraceWriter* trace_writer) {
102 return new TraceBufferRingBuffer(max_chunks, trace_writer);