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