| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/trace_event/trace_buffer.h" | 5 #include "base/trace_event/trace_buffer.h" |
| 6 | 6 |
| 7 #include <memory> |
| 7 #include <utility> | 8 #include <utility> |
| 8 #include <vector> | 9 #include <vector> |
| 9 | 10 |
| 10 #include "base/macros.h" | 11 #include "base/macros.h" |
| 11 #include "base/memory/scoped_ptr.h" | |
| 12 #include "base/trace_event/trace_event_impl.h" | 12 #include "base/trace_event/trace_event_impl.h" |
| 13 | 13 |
| 14 namespace base { | 14 namespace base { |
| 15 namespace trace_event { | 15 namespace trace_event { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 class TraceBufferRingBuffer : public TraceBuffer { | 19 class TraceBufferRingBuffer : public TraceBuffer { |
| 20 public: | 20 public: |
| 21 TraceBufferRingBuffer(size_t max_chunks) | 21 TraceBufferRingBuffer(size_t max_chunks) |
| 22 : max_chunks_(max_chunks), | 22 : max_chunks_(max_chunks), |
| 23 recyclable_chunks_queue_(new size_t[queue_capacity()]), | 23 recyclable_chunks_queue_(new size_t[queue_capacity()]), |
| 24 queue_head_(0), | 24 queue_head_(0), |
| 25 queue_tail_(max_chunks), | 25 queue_tail_(max_chunks), |
| 26 current_iteration_index_(0), | 26 current_iteration_index_(0), |
| 27 current_chunk_seq_(1) { | 27 current_chunk_seq_(1) { |
| 28 chunks_.reserve(max_chunks); | 28 chunks_.reserve(max_chunks); |
| 29 for (size_t i = 0; i < max_chunks; ++i) | 29 for (size_t i = 0; i < max_chunks; ++i) |
| 30 recyclable_chunks_queue_[i] = i; | 30 recyclable_chunks_queue_[i] = i; |
| 31 } | 31 } |
| 32 | 32 |
| 33 scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) override { | 33 std::unique_ptr<TraceBufferChunk> GetChunk(size_t* index) override { |
| 34 // Because the number of threads is much less than the number of chunks, | 34 // Because the number of threads is much less than the number of chunks, |
| 35 // the queue should never be empty. | 35 // the queue should never be empty. |
| 36 DCHECK(!QueueIsEmpty()); | 36 DCHECK(!QueueIsEmpty()); |
| 37 | 37 |
| 38 *index = recyclable_chunks_queue_[queue_head_]; | 38 *index = recyclable_chunks_queue_[queue_head_]; |
| 39 queue_head_ = NextQueueIndex(queue_head_); | 39 queue_head_ = NextQueueIndex(queue_head_); |
| 40 current_iteration_index_ = queue_head_; | 40 current_iteration_index_ = queue_head_; |
| 41 | 41 |
| 42 if (*index >= chunks_.size()) | 42 if (*index >= chunks_.size()) |
| 43 chunks_.resize(*index + 1); | 43 chunks_.resize(*index + 1); |
| 44 | 44 |
| 45 TraceBufferChunk* chunk = chunks_[*index].release(); | 45 TraceBufferChunk* chunk = chunks_[*index].release(); |
| 46 chunks_[*index] = NULL; // Put NULL in the slot of a in-flight chunk. | 46 chunks_[*index] = NULL; // Put NULL in the slot of a in-flight chunk. |
| 47 if (chunk) | 47 if (chunk) |
| 48 chunk->Reset(current_chunk_seq_++); | 48 chunk->Reset(current_chunk_seq_++); |
| 49 else | 49 else |
| 50 chunk = new TraceBufferChunk(current_chunk_seq_++); | 50 chunk = new TraceBufferChunk(current_chunk_seq_++); |
| 51 | 51 |
| 52 return scoped_ptr<TraceBufferChunk>(chunk); | 52 return std::unique_ptr<TraceBufferChunk>(chunk); |
| 53 } | 53 } |
| 54 | 54 |
| 55 void ReturnChunk(size_t index, scoped_ptr<TraceBufferChunk> chunk) override { | 55 void ReturnChunk(size_t index, |
| 56 std::unique_ptr<TraceBufferChunk> chunk) override { |
| 56 // When this method is called, the queue should not be full because it | 57 // When this method is called, the queue should not be full because it |
| 57 // can contain all chunks including the one to be returned. | 58 // can contain all chunks including the one to be returned. |
| 58 DCHECK(!QueueIsFull()); | 59 DCHECK(!QueueIsFull()); |
| 59 DCHECK(chunk); | 60 DCHECK(chunk); |
| 60 DCHECK_LT(index, chunks_.size()); | 61 DCHECK_LT(index, chunks_.size()); |
| 61 DCHECK(!chunks_[index]); | 62 DCHECK(!chunks_[index]); |
| 62 chunks_[index] = std::move(chunk); | 63 chunks_[index] = std::move(chunk); |
| 63 recyclable_chunks_queue_[queue_tail_] = index; | 64 recyclable_chunks_queue_[queue_tail_] = index; |
| 64 queue_tail_ = NextQueueIndex(queue_tail_); | 65 queue_tail_ = NextQueueIndex(queue_tail_); |
| 65 } | 66 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 } | 129 } |
| 129 | 130 |
| 130 size_t NextQueueIndex(size_t index) const { | 131 size_t NextQueueIndex(size_t index) const { |
| 131 index++; | 132 index++; |
| 132 if (index >= queue_capacity()) | 133 if (index >= queue_capacity()) |
| 133 index = 0; | 134 index = 0; |
| 134 return index; | 135 return index; |
| 135 } | 136 } |
| 136 | 137 |
| 137 size_t max_chunks_; | 138 size_t max_chunks_; |
| 138 std::vector<scoped_ptr<TraceBufferChunk>> chunks_; | 139 std::vector<std::unique_ptr<TraceBufferChunk>> chunks_; |
| 139 | 140 |
| 140 scoped_ptr<size_t[]> recyclable_chunks_queue_; | 141 std::unique_ptr<size_t[]> recyclable_chunks_queue_; |
| 141 size_t queue_head_; | 142 size_t queue_head_; |
| 142 size_t queue_tail_; | 143 size_t queue_tail_; |
| 143 | 144 |
| 144 size_t current_iteration_index_; | 145 size_t current_iteration_index_; |
| 145 uint32_t current_chunk_seq_; | 146 uint32_t current_chunk_seq_; |
| 146 | 147 |
| 147 DISALLOW_COPY_AND_ASSIGN(TraceBufferRingBuffer); | 148 DISALLOW_COPY_AND_ASSIGN(TraceBufferRingBuffer); |
| 148 }; | 149 }; |
| 149 | 150 |
| 150 class TraceBufferVector : public TraceBuffer { | 151 class TraceBufferVector : public TraceBuffer { |
| 151 public: | 152 public: |
| 152 TraceBufferVector(size_t max_chunks) | 153 TraceBufferVector(size_t max_chunks) |
| 153 : in_flight_chunk_count_(0), | 154 : in_flight_chunk_count_(0), |
| 154 current_iteration_index_(0), | 155 current_iteration_index_(0), |
| 155 max_chunks_(max_chunks) { | 156 max_chunks_(max_chunks) { |
| 156 chunks_.reserve(max_chunks_); | 157 chunks_.reserve(max_chunks_); |
| 157 } | 158 } |
| 158 | 159 |
| 159 scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) override { | 160 std::unique_ptr<TraceBufferChunk> GetChunk(size_t* index) override { |
| 160 // This function may be called when adding normal events or indirectly from | 161 // This function may be called when adding normal events or indirectly from |
| 161 // AddMetadataEventsWhileLocked(). We can not DECHECK(!IsFull()) because we | 162 // AddMetadataEventsWhileLocked(). We can not DECHECK(!IsFull()) because we |
| 162 // have to add the metadata events and flush thread-local buffers even if | 163 // have to add the metadata events and flush thread-local buffers even if |
| 163 // the buffer is full. | 164 // the buffer is full. |
| 164 *index = chunks_.size(); | 165 *index = chunks_.size(); |
| 165 chunks_.push_back(NULL); // Put NULL in the slot of a in-flight chunk. | 166 chunks_.push_back(NULL); // Put NULL in the slot of a in-flight chunk. |
| 166 ++in_flight_chunk_count_; | 167 ++in_flight_chunk_count_; |
| 167 // + 1 because zero chunk_seq is not allowed. | 168 // + 1 because zero chunk_seq is not allowed. |
| 168 return scoped_ptr<TraceBufferChunk>( | 169 return std::unique_ptr<TraceBufferChunk>( |
| 169 new TraceBufferChunk(static_cast<uint32_t>(*index) + 1)); | 170 new TraceBufferChunk(static_cast<uint32_t>(*index) + 1)); |
| 170 } | 171 } |
| 171 | 172 |
| 172 void ReturnChunk(size_t index, scoped_ptr<TraceBufferChunk> chunk) override { | 173 void ReturnChunk(size_t index, |
| 174 std::unique_ptr<TraceBufferChunk> chunk) override { |
| 173 DCHECK_GT(in_flight_chunk_count_, 0u); | 175 DCHECK_GT(in_flight_chunk_count_, 0u); |
| 174 DCHECK_LT(index, chunks_.size()); | 176 DCHECK_LT(index, chunks_.size()); |
| 175 DCHECK(!chunks_[index]); | 177 DCHECK(!chunks_[index]); |
| 176 --in_flight_chunk_count_; | 178 --in_flight_chunk_count_; |
| 177 chunks_[index] = chunk.release(); | 179 chunks_[index] = chunk.release(); |
| 178 } | 180 } |
| 179 | 181 |
| 180 bool IsFull() const override { return chunks_.size() >= max_chunks_; } | 182 bool IsFull() const override { return chunks_.size() >= max_chunks_; } |
| 181 | 183 |
| 182 size_t Size() const override { | 184 size_t Size() const override { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 TraceBuffer* TraceBuffer::CreateTraceBufferRingBuffer(size_t max_chunks) { | 330 TraceBuffer* TraceBuffer::CreateTraceBufferRingBuffer(size_t max_chunks) { |
| 329 return new TraceBufferRingBuffer(max_chunks); | 331 return new TraceBufferRingBuffer(max_chunks); |
| 330 } | 332 } |
| 331 | 333 |
| 332 TraceBuffer* TraceBuffer::CreateTraceBufferVectorOfSize(size_t max_chunks) { | 334 TraceBuffer* TraceBuffer::CreateTraceBufferVectorOfSize(size_t max_chunks) { |
| 333 return new TraceBufferVector(max_chunks); | 335 return new TraceBufferVector(max_chunks); |
| 334 } | 336 } |
| 335 | 337 |
| 336 } // namespace trace_event | 338 } // namespace trace_event |
| 337 } // namespace base | 339 } // namespace base |
| OLD | NEW |