| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/debug/trace_event_impl.h" | 5 #include "base/debug/trace_event_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/base_switches.h" | 9 #include "base/base_switches.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 recyclable_chunks_queue_(new size_t[queue_capacity()]), | 133 recyclable_chunks_queue_(new size_t[queue_capacity()]), |
| 134 queue_head_(0), | 134 queue_head_(0), |
| 135 queue_tail_(max_chunks), | 135 queue_tail_(max_chunks), |
| 136 current_iteration_index_(0), | 136 current_iteration_index_(0), |
| 137 current_chunk_seq_(1) { | 137 current_chunk_seq_(1) { |
| 138 chunks_.reserve(max_chunks); | 138 chunks_.reserve(max_chunks); |
| 139 for (size_t i = 0; i < max_chunks; ++i) | 139 for (size_t i = 0; i < max_chunks; ++i) |
| 140 recyclable_chunks_queue_[i] = i; | 140 recyclable_chunks_queue_[i] = i; |
| 141 } | 141 } |
| 142 | 142 |
| 143 virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) OVERRIDE { | 143 scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) override { |
| 144 // Because the number of threads is much less than the number of chunks, | 144 // Because the number of threads is much less than the number of chunks, |
| 145 // the queue should never be empty. | 145 // the queue should never be empty. |
| 146 DCHECK(!QueueIsEmpty()); | 146 DCHECK(!QueueIsEmpty()); |
| 147 | 147 |
| 148 *index = recyclable_chunks_queue_[queue_head_]; | 148 *index = recyclable_chunks_queue_[queue_head_]; |
| 149 queue_head_ = NextQueueIndex(queue_head_); | 149 queue_head_ = NextQueueIndex(queue_head_); |
| 150 current_iteration_index_ = queue_head_; | 150 current_iteration_index_ = queue_head_; |
| 151 | 151 |
| 152 if (*index >= chunks_.size()) | 152 if (*index >= chunks_.size()) |
| 153 chunks_.resize(*index + 1); | 153 chunks_.resize(*index + 1); |
| 154 | 154 |
| 155 TraceBufferChunk* chunk = chunks_[*index]; | 155 TraceBufferChunk* chunk = chunks_[*index]; |
| 156 chunks_[*index] = NULL; // Put NULL in the slot of a in-flight chunk. | 156 chunks_[*index] = NULL; // Put NULL in the slot of a in-flight chunk. |
| 157 if (chunk) | 157 if (chunk) |
| 158 chunk->Reset(current_chunk_seq_++); | 158 chunk->Reset(current_chunk_seq_++); |
| 159 else | 159 else |
| 160 chunk = new TraceBufferChunk(current_chunk_seq_++); | 160 chunk = new TraceBufferChunk(current_chunk_seq_++); |
| 161 | 161 |
| 162 return scoped_ptr<TraceBufferChunk>(chunk); | 162 return scoped_ptr<TraceBufferChunk>(chunk); |
| 163 } | 163 } |
| 164 | 164 |
| 165 virtual void ReturnChunk(size_t index, | 165 void ReturnChunk(size_t index, scoped_ptr<TraceBufferChunk> chunk) override { |
| 166 scoped_ptr<TraceBufferChunk> chunk) OVERRIDE { | |
| 167 // When this method is called, the queue should not be full because it | 166 // When this method is called, the queue should not be full because it |
| 168 // can contain all chunks including the one to be returned. | 167 // can contain all chunks including the one to be returned. |
| 169 DCHECK(!QueueIsFull()); | 168 DCHECK(!QueueIsFull()); |
| 170 DCHECK(chunk); | 169 DCHECK(chunk); |
| 171 DCHECK_LT(index, chunks_.size()); | 170 DCHECK_LT(index, chunks_.size()); |
| 172 DCHECK(!chunks_[index]); | 171 DCHECK(!chunks_[index]); |
| 173 chunks_[index] = chunk.release(); | 172 chunks_[index] = chunk.release(); |
| 174 recyclable_chunks_queue_[queue_tail_] = index; | 173 recyclable_chunks_queue_[queue_tail_] = index; |
| 175 queue_tail_ = NextQueueIndex(queue_tail_); | 174 queue_tail_ = NextQueueIndex(queue_tail_); |
| 176 } | 175 } |
| 177 | 176 |
| 178 virtual bool IsFull() const OVERRIDE { | 177 bool IsFull() const override { return false; } |
| 179 return false; | |
| 180 } | |
| 181 | 178 |
| 182 virtual size_t Size() const OVERRIDE { | 179 size_t Size() const override { |
| 183 // This is approximate because not all of the chunks are full. | 180 // This is approximate because not all of the chunks are full. |
| 184 return chunks_.size() * kTraceBufferChunkSize; | 181 return chunks_.size() * kTraceBufferChunkSize; |
| 185 } | 182 } |
| 186 | 183 |
| 187 virtual size_t Capacity() const OVERRIDE { | 184 size_t Capacity() const override { |
| 188 return max_chunks_ * kTraceBufferChunkSize; | 185 return max_chunks_ * kTraceBufferChunkSize; |
| 189 } | 186 } |
| 190 | 187 |
| 191 virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) OVERRIDE { | 188 TraceEvent* GetEventByHandle(TraceEventHandle handle) override { |
| 192 if (handle.chunk_index >= chunks_.size()) | 189 if (handle.chunk_index >= chunks_.size()) |
| 193 return NULL; | 190 return NULL; |
| 194 TraceBufferChunk* chunk = chunks_[handle.chunk_index]; | 191 TraceBufferChunk* chunk = chunks_[handle.chunk_index]; |
| 195 if (!chunk || chunk->seq() != handle.chunk_seq) | 192 if (!chunk || chunk->seq() != handle.chunk_seq) |
| 196 return NULL; | 193 return NULL; |
| 197 return chunk->GetEventAt(handle.event_index); | 194 return chunk->GetEventAt(handle.event_index); |
| 198 } | 195 } |
| 199 | 196 |
| 200 virtual const TraceBufferChunk* NextChunk() OVERRIDE { | 197 const TraceBufferChunk* NextChunk() override { |
| 201 if (chunks_.empty()) | 198 if (chunks_.empty()) |
| 202 return NULL; | 199 return NULL; |
| 203 | 200 |
| 204 while (current_iteration_index_ != queue_tail_) { | 201 while (current_iteration_index_ != queue_tail_) { |
| 205 size_t chunk_index = recyclable_chunks_queue_[current_iteration_index_]; | 202 size_t chunk_index = recyclable_chunks_queue_[current_iteration_index_]; |
| 206 current_iteration_index_ = NextQueueIndex(current_iteration_index_); | 203 current_iteration_index_ = NextQueueIndex(current_iteration_index_); |
| 207 if (chunk_index >= chunks_.size()) // Skip uninitialized chunks. | 204 if (chunk_index >= chunks_.size()) // Skip uninitialized chunks. |
| 208 continue; | 205 continue; |
| 209 DCHECK(chunks_[chunk_index]); | 206 DCHECK(chunks_[chunk_index]); |
| 210 return chunks_[chunk_index]; | 207 return chunks_[chunk_index]; |
| 211 } | 208 } |
| 212 return NULL; | 209 return NULL; |
| 213 } | 210 } |
| 214 | 211 |
| 215 virtual scoped_ptr<TraceBuffer> CloneForIteration() const OVERRIDE { | 212 scoped_ptr<TraceBuffer> CloneForIteration() const override { |
| 216 scoped_ptr<ClonedTraceBuffer> cloned_buffer(new ClonedTraceBuffer()); | 213 scoped_ptr<ClonedTraceBuffer> cloned_buffer(new ClonedTraceBuffer()); |
| 217 for (size_t queue_index = queue_head_; queue_index != queue_tail_; | 214 for (size_t queue_index = queue_head_; queue_index != queue_tail_; |
| 218 queue_index = NextQueueIndex(queue_index)) { | 215 queue_index = NextQueueIndex(queue_index)) { |
| 219 size_t chunk_index = recyclable_chunks_queue_[queue_index]; | 216 size_t chunk_index = recyclable_chunks_queue_[queue_index]; |
| 220 if (chunk_index >= chunks_.size()) // Skip uninitialized chunks. | 217 if (chunk_index >= chunks_.size()) // Skip uninitialized chunks. |
| 221 continue; | 218 continue; |
| 222 TraceBufferChunk* chunk = chunks_[chunk_index]; | 219 TraceBufferChunk* chunk = chunks_[chunk_index]; |
| 223 cloned_buffer->chunks_.push_back(chunk ? chunk->Clone().release() : NULL); | 220 cloned_buffer->chunks_.push_back(chunk ? chunk->Clone().release() : NULL); |
| 224 } | 221 } |
| 225 return cloned_buffer.PassAs<TraceBuffer>(); | 222 return cloned_buffer.PassAs<TraceBuffer>(); |
| 226 } | 223 } |
| 227 | 224 |
| 228 private: | 225 private: |
| 229 class ClonedTraceBuffer : public TraceBuffer { | 226 class ClonedTraceBuffer : public TraceBuffer { |
| 230 public: | 227 public: |
| 231 ClonedTraceBuffer() : current_iteration_index_(0) {} | 228 ClonedTraceBuffer() : current_iteration_index_(0) {} |
| 232 | 229 |
| 233 // The only implemented method. | 230 // The only implemented method. |
| 234 virtual const TraceBufferChunk* NextChunk() OVERRIDE { | 231 const TraceBufferChunk* NextChunk() override { |
| 235 return current_iteration_index_ < chunks_.size() ? | 232 return current_iteration_index_ < chunks_.size() ? |
| 236 chunks_[current_iteration_index_++] : NULL; | 233 chunks_[current_iteration_index_++] : NULL; |
| 237 } | 234 } |
| 238 | 235 |
| 239 virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) OVERRIDE { | 236 scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) override { |
| 240 NOTIMPLEMENTED(); | 237 NOTIMPLEMENTED(); |
| 241 return scoped_ptr<TraceBufferChunk>(); | 238 return scoped_ptr<TraceBufferChunk>(); |
| 242 } | 239 } |
| 243 virtual void ReturnChunk(size_t index, | 240 void ReturnChunk(size_t index, scoped_ptr<TraceBufferChunk>) override { |
| 244 scoped_ptr<TraceBufferChunk>) OVERRIDE { | |
| 245 NOTIMPLEMENTED(); | 241 NOTIMPLEMENTED(); |
| 246 } | 242 } |
| 247 virtual bool IsFull() const OVERRIDE { return false; } | 243 bool IsFull() const override { return false; } |
| 248 virtual size_t Size() const OVERRIDE { return 0; } | 244 size_t Size() const override { return 0; } |
| 249 virtual size_t Capacity() const OVERRIDE { return 0; } | 245 size_t Capacity() const override { return 0; } |
| 250 virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) OVERRIDE { | 246 TraceEvent* GetEventByHandle(TraceEventHandle handle) override { |
| 251 return NULL; | 247 return NULL; |
| 252 } | 248 } |
| 253 virtual scoped_ptr<TraceBuffer> CloneForIteration() const OVERRIDE { | 249 scoped_ptr<TraceBuffer> CloneForIteration() const override { |
| 254 NOTIMPLEMENTED(); | 250 NOTIMPLEMENTED(); |
| 255 return scoped_ptr<TraceBuffer>(); | 251 return scoped_ptr<TraceBuffer>(); |
| 256 } | 252 } |
| 257 | 253 |
| 258 size_t current_iteration_index_; | 254 size_t current_iteration_index_; |
| 259 ScopedVector<TraceBufferChunk> chunks_; | 255 ScopedVector<TraceBufferChunk> chunks_; |
| 260 }; | 256 }; |
| 261 | 257 |
| 262 bool QueueIsEmpty() const { | 258 bool QueueIsEmpty() const { |
| 263 return queue_head_ == queue_tail_; | 259 return queue_head_ == queue_tail_; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 | 295 |
| 300 class TraceBufferVector : public TraceBuffer { | 296 class TraceBufferVector : public TraceBuffer { |
| 301 public: | 297 public: |
| 302 TraceBufferVector(size_t max_chunks) | 298 TraceBufferVector(size_t max_chunks) |
| 303 : in_flight_chunk_count_(0), | 299 : in_flight_chunk_count_(0), |
| 304 current_iteration_index_(0), | 300 current_iteration_index_(0), |
| 305 max_chunks_(max_chunks) { | 301 max_chunks_(max_chunks) { |
| 306 chunks_.reserve(max_chunks_); | 302 chunks_.reserve(max_chunks_); |
| 307 } | 303 } |
| 308 | 304 |
| 309 virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) OVERRIDE { | 305 scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) override { |
| 310 // This function may be called when adding normal events or indirectly from | 306 // This function may be called when adding normal events or indirectly from |
| 311 // AddMetadataEventsWhileLocked(). We can not DECHECK(!IsFull()) because we | 307 // AddMetadataEventsWhileLocked(). We can not DECHECK(!IsFull()) because we |
| 312 // have to add the metadata events and flush thread-local buffers even if | 308 // have to add the metadata events and flush thread-local buffers even if |
| 313 // the buffer is full. | 309 // the buffer is full. |
| 314 *index = chunks_.size(); | 310 *index = chunks_.size(); |
| 315 chunks_.push_back(NULL); // Put NULL in the slot of a in-flight chunk. | 311 chunks_.push_back(NULL); // Put NULL in the slot of a in-flight chunk. |
| 316 ++in_flight_chunk_count_; | 312 ++in_flight_chunk_count_; |
| 317 // + 1 because zero chunk_seq is not allowed. | 313 // + 1 because zero chunk_seq is not allowed. |
| 318 return scoped_ptr<TraceBufferChunk>( | 314 return scoped_ptr<TraceBufferChunk>( |
| 319 new TraceBufferChunk(static_cast<uint32>(*index) + 1)); | 315 new TraceBufferChunk(static_cast<uint32>(*index) + 1)); |
| 320 } | 316 } |
| 321 | 317 |
| 322 virtual void ReturnChunk(size_t index, | 318 void ReturnChunk(size_t index, scoped_ptr<TraceBufferChunk> chunk) override { |
| 323 scoped_ptr<TraceBufferChunk> chunk) OVERRIDE { | |
| 324 DCHECK_GT(in_flight_chunk_count_, 0u); | 319 DCHECK_GT(in_flight_chunk_count_, 0u); |
| 325 DCHECK_LT(index, chunks_.size()); | 320 DCHECK_LT(index, chunks_.size()); |
| 326 DCHECK(!chunks_[index]); | 321 DCHECK(!chunks_[index]); |
| 327 --in_flight_chunk_count_; | 322 --in_flight_chunk_count_; |
| 328 chunks_[index] = chunk.release(); | 323 chunks_[index] = chunk.release(); |
| 329 } | 324 } |
| 330 | 325 |
| 331 virtual bool IsFull() const OVERRIDE { | 326 bool IsFull() const override { return chunks_.size() >= max_chunks_; } |
| 332 return chunks_.size() >= max_chunks_; | |
| 333 } | |
| 334 | 327 |
| 335 virtual size_t Size() const OVERRIDE { | 328 size_t Size() const override { |
| 336 // This is approximate because not all of the chunks are full. | 329 // This is approximate because not all of the chunks are full. |
| 337 return chunks_.size() * kTraceBufferChunkSize; | 330 return chunks_.size() * kTraceBufferChunkSize; |
| 338 } | 331 } |
| 339 | 332 |
| 340 virtual size_t Capacity() const OVERRIDE { | 333 size_t Capacity() const override { |
| 341 return max_chunks_ * kTraceBufferChunkSize; | 334 return max_chunks_ * kTraceBufferChunkSize; |
| 342 } | 335 } |
| 343 | 336 |
| 344 virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) OVERRIDE { | 337 TraceEvent* GetEventByHandle(TraceEventHandle handle) override { |
| 345 if (handle.chunk_index >= chunks_.size()) | 338 if (handle.chunk_index >= chunks_.size()) |
| 346 return NULL; | 339 return NULL; |
| 347 TraceBufferChunk* chunk = chunks_[handle.chunk_index]; | 340 TraceBufferChunk* chunk = chunks_[handle.chunk_index]; |
| 348 if (!chunk || chunk->seq() != handle.chunk_seq) | 341 if (!chunk || chunk->seq() != handle.chunk_seq) |
| 349 return NULL; | 342 return NULL; |
| 350 return chunk->GetEventAt(handle.event_index); | 343 return chunk->GetEventAt(handle.event_index); |
| 351 } | 344 } |
| 352 | 345 |
| 353 virtual const TraceBufferChunk* NextChunk() OVERRIDE { | 346 const TraceBufferChunk* NextChunk() override { |
| 354 while (current_iteration_index_ < chunks_.size()) { | 347 while (current_iteration_index_ < chunks_.size()) { |
| 355 // Skip in-flight chunks. | 348 // Skip in-flight chunks. |
| 356 const TraceBufferChunk* chunk = chunks_[current_iteration_index_++]; | 349 const TraceBufferChunk* chunk = chunks_[current_iteration_index_++]; |
| 357 if (chunk) | 350 if (chunk) |
| 358 return chunk; | 351 return chunk; |
| 359 } | 352 } |
| 360 return NULL; | 353 return NULL; |
| 361 } | 354 } |
| 362 | 355 |
| 363 virtual scoped_ptr<TraceBuffer> CloneForIteration() const OVERRIDE { | 356 scoped_ptr<TraceBuffer> CloneForIteration() const override { |
| 364 NOTIMPLEMENTED(); | 357 NOTIMPLEMENTED(); |
| 365 return scoped_ptr<TraceBuffer>(); | 358 return scoped_ptr<TraceBuffer>(); |
| 366 } | 359 } |
| 367 | 360 |
| 368 private: | 361 private: |
| 369 size_t in_flight_chunk_count_; | 362 size_t in_flight_chunk_count_; |
| 370 size_t current_iteration_index_; | 363 size_t current_iteration_index_; |
| 371 size_t max_chunks_; | 364 size_t max_chunks_; |
| 372 ScopedVector<TraceBufferChunk> chunks_; | 365 ScopedVector<TraceBufferChunk> chunks_; |
| 373 | 366 |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 TraceSampleCallback callback; | 855 TraceSampleCallback callback; |
| 863 }; | 856 }; |
| 864 | 857 |
| 865 // This object must be created on the IO thread. | 858 // This object must be created on the IO thread. |
| 866 class TraceSamplingThread : public PlatformThread::Delegate { | 859 class TraceSamplingThread : public PlatformThread::Delegate { |
| 867 public: | 860 public: |
| 868 TraceSamplingThread(); | 861 TraceSamplingThread(); |
| 869 virtual ~TraceSamplingThread(); | 862 virtual ~TraceSamplingThread(); |
| 870 | 863 |
| 871 // Implementation of PlatformThread::Delegate: | 864 // Implementation of PlatformThread::Delegate: |
| 872 virtual void ThreadMain() OVERRIDE; | 865 void ThreadMain() override; |
| 873 | 866 |
| 874 static void DefaultSamplingCallback(TraceBucketData* bucekt_data); | 867 static void DefaultSamplingCallback(TraceBucketData* bucekt_data); |
| 875 | 868 |
| 876 void Stop(); | 869 void Stop(); |
| 877 void WaitSamplingEventForTesting(); | 870 void WaitSamplingEventForTesting(); |
| 878 | 871 |
| 879 private: | 872 private: |
| 880 friend class TraceLog; | 873 friend class TraceLog; |
| 881 | 874 |
| 882 void GetSamples(); | 875 void GetSamples(); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 handle.chunk_index != chunk_index_) | 1052 handle.chunk_index != chunk_index_) |
| 1060 return NULL; | 1053 return NULL; |
| 1061 | 1054 |
| 1062 return chunk_->GetEventAt(handle.event_index); | 1055 return chunk_->GetEventAt(handle.event_index); |
| 1063 } | 1056 } |
| 1064 | 1057 |
| 1065 int generation() const { return generation_; } | 1058 int generation() const { return generation_; } |
| 1066 | 1059 |
| 1067 private: | 1060 private: |
| 1068 // MessageLoop::DestructionObserver | 1061 // MessageLoop::DestructionObserver |
| 1069 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; | 1062 void WillDestroyCurrentMessageLoop() override; |
| 1070 | 1063 |
| 1071 void FlushWhileLocked(); | 1064 void FlushWhileLocked(); |
| 1072 | 1065 |
| 1073 void CheckThisIsCurrentBuffer() const { | 1066 void CheckThisIsCurrentBuffer() const { |
| 1074 DCHECK(trace_log_->thread_local_event_buffer_.Get() == this); | 1067 DCHECK(trace_log_->thread_local_event_buffer_.Get() == this); |
| 1075 } | 1068 } |
| 1076 | 1069 |
| 1077 // Since TraceLog is a leaky singleton, trace_log_ will always be valid | 1070 // Since TraceLog is a leaky singleton, trace_log_ will always be valid |
| 1078 // as long as the thread exists. | 1071 // as long as the thread exists. |
| 1079 TraceLog* trace_log_; | 1072 TraceLog* trace_log_; |
| (...skipping 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2571 } | 2564 } |
| 2572 | 2565 |
| 2573 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { | 2566 ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { |
| 2574 if (*category_group_enabled_) { | 2567 if (*category_group_enabled_) { |
| 2575 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, | 2568 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, |
| 2576 name_, event_handle_); | 2569 name_, event_handle_); |
| 2577 } | 2570 } |
| 2578 } | 2571 } |
| 2579 | 2572 |
| 2580 } // namespace trace_event_internal | 2573 } // namespace trace_event_internal |
| OLD | NEW |