Chromium Code Reviews| Index: components/tracing/core/trace_ring_buffer.cc |
| diff --git a/components/tracing/core/trace_ring_buffer.cc b/components/tracing/core/trace_ring_buffer.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5f6482a073e4456a71ab9ed9a4944649e301696a |
| --- /dev/null |
| +++ b/components/tracing/core/trace_ring_buffer.cc |
| @@ -0,0 +1,73 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/tracing/core/trace_ring_buffer.h" |
| + |
| +#include "base/threading/platform_thread.h" |
| + |
| +namespace tracing { |
| +namespace v2 { |
| + |
| +TraceRingBuffer::TraceRingBuffer(uint8_t* begin, size_t size) |
| + : num_chunks_(size / Chunk::kSize), current_chunk_idx_(0) { |
| + DCHECK_GE(size, Chunk::kSize); |
|
petrcermak
2016/06/28 10:22:29
maybe check DCHECK_GT(num_chunks_, 0) since that's
Primiano Tucci (use gerrit)
2016/06/28 11:30:14
makes sense, thanks. Done
|
| + DCHECK_EQ(0ul, reinterpret_cast<uintptr_t>(begin) % sizeof(uintptr_t)); |
| + chunks_.reset(new Chunk[num_chunks_]); |
| + uint8_t* chunk_begin = begin; |
| + for (size_t i = 0; i < num_chunks_; ++i) { |
| + chunks_[i].Initialize(chunk_begin); |
| + chunk_begin = chunk_begin + Chunk::kSize; |
|
petrcermak
2016/06/28 10:22:29
chunk_begin += Chunk::kSize
alternatively, use mu
Primiano Tucci (use gerrit)
2016/06/28 11:30:14
Oh definitely. The only reason why it is that way
|
| + } |
| +} |
| + |
| +TraceRingBuffer::~TraceRingBuffer() {} |
| + |
| +TraceRingBuffer::Chunk* TraceRingBuffer::TakeChunk() { |
| + base::AutoLock lock(lock_); |
| + DCHECK_GT(num_chunks_, 0ul); |
| + DCHECK_LT(current_chunk_idx_, num_chunks_); |
| + Chunk* chunk = nullptr; |
|
petrcermak
2016/06/28 10:22:29
Why don't you declare this inside the loop on line
Primiano Tucci (use gerrit)
2016/06/28 11:30:14
Same as above, historical evolution of this code.
|
| + for (size_t i = 0; i < num_chunks_; ++i) { |
| + chunk = &chunks_[current_chunk_idx_]; |
| + current_chunk_idx_ = (current_chunk_idx_ + 1) % num_chunks_; |
| + if (!chunk->is_owned()) { |
| + chunk->Clear(); |
| + chunk->set_owner(base::PlatformThread::CurrentId()); |
| + return chunk; |
| + } |
| + } |
| + |
| + // Bankrupcy: there are more threads than chunks. All chunks were on flight. |
|
petrcermak
2016/06/28 10:22:29
nit: s/on/in/
Primiano Tucci (use gerrit)
2016/06/28 11:30:14
Done.
|
| + if (!bankrupcy_chunk_storage_) { |
| + bankrupcy_chunk_storage_.reset(new uint8_t[Chunk::kSize]); |
| + uint8_t* const begin = &bankrupcy_chunk_storage_.get()[0]; |
|
petrcermak
2016/06/28 10:22:29
Opinion: I don't think that naming this "begin" ma
Primiano Tucci (use gerrit)
2016/06/28 11:30:14
Oh, as above. Before there was a "begin" and "end"
|
| + bankrupcy_chunk_.Initialize(begin); |
| + } |
| + bankrupcy_chunk_.Clear(); |
| + return &bankrupcy_chunk_; |
| +} |
| + |
| +void TraceRingBuffer::ReturnChunk(TraceRingBuffer::Chunk* chunk, |
| + uint32_t used_size) { |
| + base::AutoLock lock(lock_); |
|
petrcermak
2016/06/28 10:22:29
Would it make sense to DCHECK that the chunk is ac
Primiano Tucci (use gerrit)
2016/06/28 11:30:14
Hmm that would make the debug (or DCHECK_ALWAYS_ON
|
| + chunk->set_used_size(used_size); |
| + chunk->clear_owner(); |
| +} |
| + |
| +TraceRingBuffer::Chunk::Chunk() |
| + : begin_(nullptr), owner_(base::kInvalidThreadId) {} |
| + |
| +TraceRingBuffer::Chunk::~Chunk() {} |
| + |
| +void TraceRingBuffer::Chunk::Clear() { |
|
petrcermak
2016/06/28 10:22:29
Shouldn't this also clear owner?
Primiano Tucci (use gerrit)
2016/06/28 11:30:14
No this one is deliberate. I mean whether conceptu
|
| + set_used_size(0); |
| +} |
| + |
| +void TraceRingBuffer::Chunk::Initialize(uint8_t* begin) { |
| + DCHECK_EQ(0ul, reinterpret_cast<uintptr_t>(begin) % sizeof(uintptr_t)); |
| + begin_ = begin; |
| +} |
| + |
| +} // namespace v2 |
| +} // namespace tracing |