Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(378)

Side by Side Diff: components/tracing/core/trace_ring_buffer.cc

Issue 2197563002: tracing v2: minor refactoring to TraceRingBuffer test helpers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: simpler check Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_ring_buffer.h" 5 #include "components/tracing/core/trace_ring_buffer.h"
6 6
7 #include "base/threading/platform_thread.h" 7 #include "base/threading/platform_thread.h"
8 8
9 namespace tracing { 9 namespace tracing {
10 namespace v2 { 10 namespace v2 {
11 11
12 TraceRingBuffer::TraceRingBuffer(uint8_t* begin, size_t size) 12 TraceRingBuffer::TraceRingBuffer(uint8_t* begin, size_t size)
13 : num_chunks_(size / Chunk::kSize), current_chunk_idx_(0) { 13 : num_chunks_(size / Chunk::kSize),
14 num_chunks_taken_(0),
15 current_chunk_idx_(0) {
14 DCHECK_GT(num_chunks_, 0u); 16 DCHECK_GT(num_chunks_, 0u);
15 DCHECK_EQ(0ul, reinterpret_cast<uintptr_t>(begin) % sizeof(uintptr_t)); 17 DCHECK_EQ(0ul, reinterpret_cast<uintptr_t>(begin) % sizeof(uintptr_t));
16 chunks_.reset(new Chunk[num_chunks_]); 18 chunks_.reset(new Chunk[num_chunks_]);
17 uint8_t* chunk_begin = begin; 19 uint8_t* chunk_begin = begin;
18 for (size_t i = 0; i < num_chunks_; ++i) { 20 for (size_t i = 0; i < num_chunks_; ++i) {
19 chunks_[i].Initialize(chunk_begin); 21 chunks_[i].Initialize(chunk_begin);
20 chunk_begin += Chunk::kSize; 22 chunk_begin += Chunk::kSize;
21 } 23 }
22 } 24 }
23 25
24 TraceRingBuffer::~TraceRingBuffer() {} 26 TraceRingBuffer::~TraceRingBuffer() {}
25 27
26 TraceRingBuffer::Chunk* TraceRingBuffer::TakeChunk() { 28 TraceRingBuffer::Chunk* TraceRingBuffer::TakeChunk(uint32_t writer_id) {
27 base::AutoLock lock(lock_); 29 base::AutoLock lock(lock_);
28 DCHECK_GT(num_chunks_, 0ul); 30 DCHECK_GT(num_chunks_, 0ul);
29 DCHECK_LT(current_chunk_idx_, num_chunks_); 31 DCHECK_LT(current_chunk_idx_, num_chunks_);
30 for (size_t i = 0; i < num_chunks_; ++i) { 32 for (size_t i = 0; i < num_chunks_; ++i) {
31 Chunk* chunk = &chunks_[current_chunk_idx_]; 33 Chunk* chunk = &chunks_[current_chunk_idx_];
32 current_chunk_idx_ = (current_chunk_idx_ + 1) % num_chunks_; 34 current_chunk_idx_ = (current_chunk_idx_ + 1) % num_chunks_;
33 if (!chunk->is_owned()) { 35 if (!chunk->is_owned()) {
34 chunk->Clear(); 36 chunk->Clear();
35 chunk->set_owner(base::PlatformThread::CurrentId()); 37 DCHECK_NE(0u, writer_id);
38 chunk->set_owner(writer_id);
39 num_chunks_taken_++;
36 return chunk; 40 return chunk;
37 } 41 }
38 } 42 }
39 43
40 // Bankrupcy: there are more threads than chunks. All chunks were in flight. 44 // Bankrupcy: there are more threads than chunks. All chunks were in flight.
41 if (!bankrupcy_chunk_storage_) { 45 if (!bankrupcy_chunk_storage_) {
42 bankrupcy_chunk_storage_.reset(new uint8_t[Chunk::kSize]); 46 bankrupcy_chunk_storage_.reset(new uint8_t[Chunk::kSize]);
43 bankrupcy_chunk_.Initialize(&bankrupcy_chunk_storage_.get()[0]); 47 bankrupcy_chunk_.Initialize(&bankrupcy_chunk_storage_.get()[0]);
44 } 48 }
45 bankrupcy_chunk_.Clear(); 49 bankrupcy_chunk_.Clear();
46 return &bankrupcy_chunk_; 50 return &bankrupcy_chunk_;
47 } 51 }
48 52
49 void TraceRingBuffer::ReturnChunk(TraceRingBuffer::Chunk* chunk, 53 void TraceRingBuffer::ReturnChunk(TraceRingBuffer::Chunk* chunk) {
50 uint32_t used_size) { 54 // Returning a chunk without using it is quite odd, very likely a bug.
55 DCHECK_GT(chunk->used_size(), 0u);
56
57 // The caller should never return chunks which are part of a retaining chain.
58 DCHECK(!chunk->next_in_owner_list());
59
60 if (chunk == &bankrupcy_chunk_)
61 return;
62
63 // TODO(primiano): this lock might be removed in favor of acquire/release
64 // semantics on the two vars below. Check once the reader of these are landed.
51 base::AutoLock lock(lock_); 65 base::AutoLock lock(lock_);
52 chunk->set_used_size(used_size);
53 chunk->clear_owner(); 66 chunk->clear_owner();
67 num_chunks_taken_--;
68 }
69
70 bool TraceRingBuffer::IsBankrupcyChunkForTesting(const Chunk* chunk) const {
71 return chunk == &bankrupcy_chunk_;
72 }
73
74 size_t TraceRingBuffer::GetNumChunksTaken() const {
75 base::AutoLock lock(lock_);
76 return num_chunks_taken_;
54 } 77 }
55 78
56 TraceRingBuffer::Chunk::Chunk() 79 TraceRingBuffer::Chunk::Chunk()
57 : begin_(nullptr), owner_(base::kInvalidThreadId) {} 80 : begin_(nullptr), owner_(kNoChunkOwner), next_in_owner_list_(nullptr) {}
58 81
59 TraceRingBuffer::Chunk::~Chunk() {} 82 TraceRingBuffer::Chunk::~Chunk() {}
60 83
61 void TraceRingBuffer::Chunk::Clear() { 84 void TraceRingBuffer::Chunk::Clear() {
62 set_used_size(0); 85 set_used_size(0);
86 set_next_in_owner_list(nullptr);
63 } 87 }
64 88
65 void TraceRingBuffer::Chunk::Initialize(uint8_t* begin) { 89 void TraceRingBuffer::Chunk::Initialize(uint8_t* begin) {
66 DCHECK_EQ(0ul, reinterpret_cast<uintptr_t>(begin) % sizeof(uintptr_t)); 90 DCHECK_EQ(0ul, reinterpret_cast<uintptr_t>(begin) % sizeof(uintptr_t));
67 begin_ = begin; 91 begin_ = begin;
68 } 92 }
69 93
70 } // namespace v2 94 } // namespace v2
71 } // namespace tracing 95 } // namespace tracing
OLDNEW
« no previous file with comments | « components/tracing/core/trace_ring_buffer.h ('k') | components/tracing/core/trace_ring_buffer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698