15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/base_switches.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/leak_annotations.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/debug/trace_event_synthetic_delay.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/float_util.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h" 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/json/string_escape.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h" 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/message_loop/message_loop.h" 2158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "base/process/process_metrics.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h" 265e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 275e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/cancellation_flag.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/waitable_event.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_info.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/third_party/dynamic_annotations/dynamic_annotations.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_id_name_manager.h" 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event_win.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DeleteTraceLogForTesting { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Delete() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Singleton<base::debug::TraceLog, 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch LeakySingletonTraits<base::debug::TraceLog> >::OnExit(0); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The thread buckets for the sampling profiler. 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochBASE_EXPORT TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3]; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace debug { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace { 5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The overhead of TraceEvent above this threshold will be reported in the 5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// trace. 5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const int kOverheadReportThresholdInMicroseconds = 50; 6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// String options that can be used to initialize TraceOptions. 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kRecordUntilFull[] = "record-until-full"; 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kRecordContinuously[] = "record-continuously"; 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kRecordAsMuchAsPossible[] = "record-as-much-as-possible"; 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kTraceToConsole[] = "trace-to-console"; 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kEnableSampling[] = "enable-sampling"; 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kEnableSystrace[] = "enable-systrace"; 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Controls the number of trace events we will buffer in-memory 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// before throwing them away. 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const size_t kTraceBufferChunkSize = TraceBufferChunk::kTraceBufferChunkSize; 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const size_t kTraceEventVectorBigBufferChunks = 736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 512000000 / kTraceBufferChunkSize; 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const size_t kTraceEventVectorBufferChunks = 256000 / kTraceBufferChunkSize; 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const size_t kTraceEventRingBufferChunks = kTraceEventVectorBufferChunks / 4; 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const size_t kTraceEventBatchChunks = 1000 / kTraceBufferChunkSize; 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Can store results for 30 seconds with 1 ms sampling interval. 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const size_t kMonitorTraceEventBufferChunks = 30000 / kTraceBufferChunkSize; 791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// ECHO_TO_CONSOLE needs a small buffer to hold the unfinished COMPLETE events. 801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const size_t kEchoToConsoleTraceEventBufferChunks = 256; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const int kThreadFlushTimeoutMs = 3000; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if !defined(OS_NACL) 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// These categories will cause deadlock when ECHO_TO_CONSOLE. crbug.com/325575. 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kEchoToConsoleCategoryFilter[] = "-ipc,-task"; 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kSyntheticDelayCategoryFilterPrefix[] = "DELAY("; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#define MAX_CATEGORY_GROUPS 100 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Parallel arrays g_category_groups and g_category_group_enabled are separate 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// so that a pointer to a member of g_category_group_enabled can be easily 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// converted to an index into g_category_groups. This allows macros to deal 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// only with char enabled pointers from g_category_group_enabled, and we can 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// convert internally to determine the category name from the char enabled 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// pointer. 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char* g_category_groups[MAX_CATEGORY_GROUPS] = { 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "toplevel", 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "tracing already shutdown", 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "tracing categories exhausted; must increase MAX_CATEGORY_GROUPS", 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "__metadata", 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // For reporting trace_event overhead. For thread local event buffers only. 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "trace_event_overhead"}; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The enabled flag is char instead of bool so that the API can be used from C. 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)unsigned char g_category_group_enabled[MAX_CATEGORY_GROUPS] = { 0 }; 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Indexes here have to match the g_category_groups array indexes above. 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int g_category_already_shutdown = 1; 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int g_category_categories_exhausted = 2; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int g_category_metadata = 3; 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int g_category_trace_event_overhead = 4; 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int g_num_builtin_categories = 5; 115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Skip default categories. 116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbase::subtle::AtomicWord g_category_index = g_num_builtin_categories; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The name of the current thread. This is used to decide if the current 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// thread name has changed. We combine all the seen thread names into the 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// output name for the thread. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LazyInstance<ThreadLocalPointer<const char> >::Leaky 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_current_thread_name = LAZY_INSTANCE_INITIALIZER; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TimeTicks ThreadNow() { 12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return TimeTicks::IsThreadNowSupported() ? 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TimeTicks::ThreadNow() : TimeTicks(); 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class TraceBufferRingBuffer : public TraceBuffer { 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferRingBuffer(size_t max_chunks) 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : max_chunks_(max_chunks), 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) recyclable_chunks_queue_(new size_t[queue_capacity()]), 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) queue_head_(0), 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) queue_tail_(max_chunks), 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_iteration_index_(0), 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_chunk_seq_(1) { 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunks_.reserve(max_chunks); 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < max_chunks; ++i) 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) recyclable_chunks_queue_[i] = i; 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) OVERRIDE { 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Because the number of threads is much less than the number of chunks, 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the queue should never be empty. 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!QueueIsEmpty()); 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *index = recyclable_chunks_queue_[queue_head_]; 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) queue_head_ = NextQueueIndex(queue_head_); 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_iteration_index_ = queue_head_; 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (*index >= chunks_.size()) 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunks_.resize(*index + 1); 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferChunk* chunk = chunks_[*index]; 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunks_[*index] = NULL; // Put NULL in the slot of a in-flight chunk. 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (chunk) 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunk->Reset(current_chunk_seq_++); 1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) else 1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunk = new TraceBufferChunk(current_chunk_seq_++); 1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return scoped_ptr<TraceBufferChunk>(chunk); 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void ReturnChunk(size_t index, 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> chunk) OVERRIDE { 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // When this method is called, the queue should not be full because it 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // can contain all chunks including the one to be returned. 1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!QueueIsFull()); 1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(chunk); 1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_LT(index, chunks_.size()); 1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!chunks_[index]); 1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunks_[index] = chunk.release(); 1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) recyclable_chunks_queue_[queue_tail_] = index; 1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) queue_tail_ = NextQueueIndex(queue_tail_); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool IsFull() const OVERRIDE { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual size_t Size() const OVERRIDE { 1834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This is approximate because not all of the chunks are full. 1844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return chunks_.size() * kTraceBufferChunkSize; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual size_t Capacity() const OVERRIDE { 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return max_chunks_ * kTraceBufferChunkSize; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) OVERRIDE { 1928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (handle.chunk_index >= chunks_.size()) 1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return NULL; 1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceBufferChunk* chunk = chunks_[handle.chunk_index]; 1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!chunk || chunk->seq() != handle.chunk_seq) 1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return NULL; 1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return chunk->GetEventAt(handle.event_index); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual const TraceBufferChunk* NextChunk() OVERRIDE { 2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (chunks_.empty()) 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) while (current_iteration_index_ != queue_tail_) { 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t chunk_index = recyclable_chunks_queue_[current_iteration_index_]; 2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_iteration_index_ = NextQueueIndex(current_iteration_index_); 2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (chunk_index >= chunks_.size()) // Skip uninitialized chunks. 2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(chunks_[chunk_index]); 2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return chunks_[chunk_index]; 2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<TraceBuffer> CloneForIteration() const OVERRIDE { 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<ClonedTraceBuffer> cloned_buffer(new ClonedTraceBuffer()); 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t queue_index = queue_head_; queue_index != queue_tail_; 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) queue_index = NextQueueIndex(queue_index)) { 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t chunk_index = recyclable_chunks_queue_[queue_index]; 2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (chunk_index >= chunks_.size()) // Skip uninitialized chunks. 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; 2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBufferChunk* chunk = chunks_[chunk_index]; 2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) cloned_buffer->chunks_.push_back(chunk ? chunk->Clone().release() : NULL); 2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return cloned_buffer.PassAs<TraceBuffer>(); 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 2291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) class ClonedTraceBuffer : public TraceBuffer { 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ClonedTraceBuffer() : current_iteration_index_(0) {} 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The only implemented method. 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual const TraceBufferChunk* NextChunk() OVERRIDE { 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return current_iteration_index_ < chunks_.size() ? 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunks_[current_iteration_index_++] : NULL; 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) OVERRIDE { 2401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NOTIMPLEMENTED(); 2411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return scoped_ptr<TraceBufferChunk>(); 2421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual void ReturnChunk(size_t index, 2441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<TraceBufferChunk>) OVERRIDE { 2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NOTIMPLEMENTED(); 2461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual bool IsFull() const OVERRIDE { return false; } 2481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual size_t Size() const OVERRIDE { return 0; } 2491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual size_t Capacity() const OVERRIDE { return 0; } 2501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) OVERRIDE { 2511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual scoped_ptr<TraceBuffer> CloneForIteration() const OVERRIDE { 2541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NOTIMPLEMENTED(); 2551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return scoped_ptr<TraceBuffer>(); 2561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 2571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t current_iteration_index_; 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedVector<TraceBufferChunk> chunks_; 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }; 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool QueueIsEmpty() const { 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return queue_head_ == queue_tail_; 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t QueueSize() const { 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return queue_tail_ > queue_head_ ? queue_tail_ - queue_head_ : 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) queue_tail_ + queue_capacity() - queue_head_; 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool QueueIsFull() const { 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return QueueSize() == queue_capacity() - 1; 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t queue_capacity() const { 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // One extra space to help distinguish full state and empty state. 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return max_chunks_ + 1; 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t NextQueueIndex(size_t index) const { 2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index++; 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (index >= queue_capacity()) 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) index = 0; 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return index; 2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t max_chunks_; 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedVector<TraceBufferChunk> chunks_; 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<size_t[]> recyclable_chunks_queue_; 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t queue_head_; 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t queue_tail_; 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t current_iteration_index_; 2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32 current_chunk_seq_; 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TraceBufferRingBuffer); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceBufferVector : public TraceBuffer { 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TraceBufferVector(size_t max_chunks) 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : in_flight_chunk_count_(0), 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current_iteration_index_(0), 3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) max_chunks_(max_chunks) { 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) chunks_.reserve(max_chunks_); 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<TraceBufferChunk> GetChunk(size_t* index) OVERRIDE { 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This function may be called when adding normal events or indirectly from 3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // AddMetadataEventsWhileLocked(). We can not DECHECK(!IsFull()) because we 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // have to add the metadata events and flush thread-local buffers even if 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // the buffer is full. 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *index = chunks_.size(); 3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunks_.push_back(NULL); // Put NULL in the slot of a in-flight chunk. 3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ++in_flight_chunk_count_; 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // + 1 because zero chunk_seq is not allowed. 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return scoped_ptr<TraceBufferChunk>( 3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new TraceBufferChunk(static_cast<uint32>(*index) + 1)); 3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void ReturnChunk(size_t index, 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> chunk) OVERRIDE { 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_GT(in_flight_chunk_count_, 0u); 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK_LT(index, chunks_.size()); 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(!chunks_[index]); 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) --in_flight_chunk_count_; 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunks_[index] = chunk.release(); 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual bool IsFull() const OVERRIDE { 3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return chunks_.size() >= max_chunks_; 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual size_t Size() const OVERRIDE { 3364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // This is approximate because not all of the chunks are full. 3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return chunks_.size() * kTraceBufferChunkSize; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual size_t Capacity() const OVERRIDE { 3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return max_chunks_ * kTraceBufferChunkSize; 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual TraceEvent* GetEventByHandle(TraceEventHandle handle) OVERRIDE { 3458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (handle.chunk_index >= chunks_.size()) 3468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return NULL; 3478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceBufferChunk* chunk = chunks_[handle.chunk_index]; 3488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!chunk || chunk->seq() != handle.chunk_seq) 3498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return NULL; 3508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return chunk->GetEventAt(handle.event_index); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual const TraceBufferChunk* NextChunk() OVERRIDE { 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) while (current_iteration_index_ < chunks_.size()) { 3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Skip in-flight chunks. 3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TraceBufferChunk* chunk = chunks_[current_iteration_index_++]; 3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (chunk) 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return chunk; 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<TraceBuffer> CloneForIteration() const OVERRIDE { 3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTIMPLEMENTED(); 3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return scoped_ptr<TraceBuffer>(); 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t in_flight_chunk_count_; 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t current_iteration_index_; 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t max_chunks_; 3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedVector<TraceBufferChunk> chunks_; 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TraceBufferVector); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)template <typename T> 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void InitializeMetadataEvent(TraceEvent* trace_event, 3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int thread_id, 3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const char* metadata_name, const char* arg_name, 3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const T& value) { 3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!trace_event) 3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int num_args = 1; 3864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned char arg_type; 3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned long long arg_value; 3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ::trace_event_internal::SetTraceValue(value, &arg_type, &arg_value); 3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) trace_event->Initialize(thread_id, 3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TimeTicks(), TimeTicks(), TRACE_EVENT_PHASE_METADATA, 3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &g_category_group_enabled[g_category_metadata], 3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) metadata_name, ::trace_event_internal::kNoEventId, 3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) num_args, &arg_name, &arg_type, &arg_value, NULL, 3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TRACE_EVENT_FLAG_NONE); 3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 397a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)class AutoThreadLocalBoolean { 398a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public: 399a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) explicit AutoThreadLocalBoolean(ThreadLocalBoolean* thread_local_boolean) 400a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : thread_local_boolean_(thread_local_boolean) { 401a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!thread_local_boolean_->Get()); 402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) thread_local_boolean_->Set(true); 403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 404a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ~AutoThreadLocalBoolean() { 405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) thread_local_boolean_->Set(false); 406a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 407a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 408a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) private: 409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ThreadLocalBoolean* thread_local_boolean_; 410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AutoThreadLocalBoolean); 411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}; 412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 4138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace 4148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TraceBufferChunk::Reset(uint32 new_seq) { 4168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (size_t i = 0; i < next_free_; ++i) 4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) chunk_[i].Reset(); 4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) next_free_ = 0; 4198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) seq_ = new_seq; 4208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TraceEvent* TraceBufferChunk::AddTraceEvent(size_t* event_index) { 4238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(!IsFull()); 4248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) *event_index = next_free_++; 4258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return &chunk_[*event_index]; 4268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)scoped_ptr<TraceBufferChunk> TraceBufferChunk::Clone() const { 4298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<TraceBufferChunk> cloned_chunk(new TraceBufferChunk(seq_)); 4308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cloned_chunk->next_free_ = next_free_; 4318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (size_t i = 0; i < next_free_; ++i) 4328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) cloned_chunk->chunk_[i].CopyFrom(chunk_[i]); 4338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return cloned_chunk.Pass(); 4348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 4358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 4364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// A helper class that allows the lock to be acquired in the middle of the scope 4374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// and unlocks at the end of scope if locked. 4388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class TraceLog::OptionalAutoLock { 4394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 4404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) explicit OptionalAutoLock(Lock& lock) 4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : lock_(lock), 4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) locked_(false) { 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ~OptionalAutoLock() { 4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (locked_) 4474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) lock_.Release(); 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void EnsureAcquired() { 4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!locked_) { 4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) lock_.Acquire(); 4534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) locked_ = true; 4544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 4584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Lock& lock_; 4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool locked_; 4604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OptionalAutoLock); 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use this function instead of TraceEventHandle constructor to keep the 4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// overhead of ScopedTracer (trace_event.h) constructor minimum. 4651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MakeHandle(uint32 chunk_seq, size_t chunk_index, size_t event_index, 4661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) TraceEventHandle* handle) { 4671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(chunk_seq); 4681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(chunk_index < (1u << 16)); 4691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(event_index < (1u << 16)); 4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle->chunk_seq = chunk_seq; 4711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle->chunk_index = static_cast<uint16>(chunk_index); 4721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) handle->event_index = static_cast<uint16>(event_index); 4731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceEvent 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copies |*member| into |*buffer|, sets |*member| to point to this new 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// location, and then advances |*buffer| by the amount written. 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CopyTraceEventParameter(char** buffer, 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char** member, 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end) { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (*member) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t written = strlcpy(*buffer, *member, end - *buffer) + 1; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(static_cast<int>(written), end - *buffer); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *member = *buffer; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *buffer += written; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceEvent::TraceEvent() 5018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) : duration_(TimeDelta::FromInternalValue(-1)), 5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) id_(0u), 503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category_group_enabled_(NULL), 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name_(NULL), 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_id_(0), 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) phase_(TRACE_EVENT_PHASE_BEGIN), 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags_(0) { 5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < kTraceMaxNumArgs; ++i) 5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) arg_names_[i] = NULL; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(arg_values_, 0, sizeof(arg_values_)); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TraceEvent::~TraceEvent() { 5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceEvent::CopyFrom(const TraceEvent& other) { 5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) timestamp_ = other.timestamp_; 5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_timestamp_ = other.thread_timestamp_; 5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) duration_ = other.duration_; 5204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) id_ = other.id_; 5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) category_group_enabled_ = other.category_group_enabled_; 5224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) name_ = other.name_; 5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_id_ = other.thread_id_; 5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) phase_ = other.phase_; 5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) flags_ = other.flags_; 5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) parameter_copy_storage_ = other.parameter_copy_storage_; 5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < kTraceMaxNumArgs; ++i) { 5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) arg_names_[i] = other.arg_names_[i]; 5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) arg_types_[i] = other.arg_types_[i]; 5314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) arg_values_[i] = other.arg_values_[i]; 5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) convertable_values_[i] = other.convertable_values_[i]; 5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceEvent::Initialize( 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int thread_id, 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TimeTicks timestamp, 5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) TimeTicks thread_timestamp, 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char phase, 541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* name, 543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned long long id, 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int num_args, 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char** arg_names, 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* arg_types, 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned long long* arg_values, 5484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 5494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned char flags) { 5504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) timestamp_ = timestamp; 5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_timestamp_ = thread_timestamp; 5528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) duration_ = TimeDelta::FromInternalValue(-1); 5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) id_ = id; 5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) category_group_enabled_ = category_group_enabled; 5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) name_ = name; 5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_id_ = thread_id; 5574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) phase_ = phase; 5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) flags_ = flags; 5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clamp num_args since it may have been set by a third_party library. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_args = (num_args > kTraceMaxNumArgs) ? kTraceMaxNumArgs : num_args; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = 0; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < num_args; ++i) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg_names_[i] = arg_names[i]; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg_types_[i] = arg_types[i]; 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (arg_types[i] == TRACE_VALUE_TYPE_CONVERTABLE) 5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) convertable_values_[i] = convertable_values[i]; 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) arg_values_[i].as_uint = arg_values[i]; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < kTraceMaxNumArgs; ++i) { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg_names_[i] = NULL; 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg_values_[i].as_uint = 0u; 5754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) convertable_values_[i] = NULL; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg_types_[i] = TRACE_VALUE_TYPE_UINT; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool copy = !!(flags & TRACE_EVENT_FLAG_COPY); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t alloc_size = 0; 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (copy) { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alloc_size += GetAllocLength(name); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_args; ++i) { 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alloc_size += GetAllocLength(arg_names_[i]); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arg_types_[i] == TRACE_VALUE_TYPE_STRING) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg_types_[i] = TRACE_VALUE_TYPE_COPY_STRING; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool arg_is_copy[kTraceMaxNumArgs]; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_args; ++i) { 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // No copying of convertable types, we retain ownership. 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We only take a copy of arg_vals if they are of type COPY_STRING. 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) arg_is_copy[i] = (arg_types_[i] == TRACE_VALUE_TYPE_COPY_STRING); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arg_is_copy[i]) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alloc_size += GetAllocLength(arg_values_[i].as_string); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (alloc_size) { 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parameter_copy_storage_ = new RefCountedString; 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parameter_copy_storage_->data().resize(alloc_size); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* ptr = string_as_array(¶meter_copy_storage_->data()); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end = ptr + alloc_size; 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (copy) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyTraceEventParameter(&ptr, &name_, end); 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (i = 0; i < num_args; ++i) { 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyTraceEventParameter(&ptr, &arg_names_[i], end); 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < num_args; ++i) { 614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (arg_is_copy[i]) 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CopyTraceEventParameter(&ptr, &arg_values_[i].as_string, end); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(end, ptr) << "Overrun by " << ptr - end; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceEvent::Reset() { 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Only reset fields that won't be initialized in Initialize(), or that may 6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // hold references to other objects. 6268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) duration_ = TimeDelta::FromInternalValue(-1); 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) parameter_copy_storage_ = NULL; 6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (int i = 0; i < kTraceMaxNumArgs; ++i) 6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) convertable_values_[i] = NULL; 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void TraceEvent::UpdateDuration(const TimeTicks& now, 633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const TimeTicks& thread_now) { 6340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(duration_.ToInternalValue() == -1); 6350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) duration_ = now - timestamp_; 636f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) thread_duration_ = thread_now - thread_timestamp_; 6370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 6380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceEvent::AppendValueAsJSON(unsigned char type, 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEvent::TraceValue value, 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* out) { 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TRACE_VALUE_TYPE_BOOL: 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out += value.as_bool ? "true" : "false"; 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TRACE_VALUE_TYPE_UINT: 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringAppendF(out, "%" PRIu64, static_cast<uint64>(value.as_uint)); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TRACE_VALUE_TYPE_INT: 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringAppendF(out, "%" PRId64, static_cast<int64>(value.as_int)); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case TRACE_VALUE_TYPE_DOUBLE: { 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // FIXME: base/json/json_writer.cc is using the same code, 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // should be made into a common method. 6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string real; 6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) double val = value.as_double; 6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsFinite(val)) { 6595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real = DoubleToString(val); 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensure that the number has a .0 if there's no decimal or 'e'. This 6615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // makes sure that when we read the JSON back, it's interpreted as a 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // real rather than an int. 6635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (real.find('.') == std::string::npos && 6645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real.find('e') == std::string::npos && 6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real.find('E') == std::string::npos) { 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real.append(".0"); 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The JSON spec requires that non-integer values in the range (-1,1) 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // have a zero before the decimal point - ".52" is not valid, "0.52" is. 6705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (real[0] == '.') { 6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real.insert(0, "0"); 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (real.length() > 1 && real[0] == '-' && real[1] == '.') { 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // "-.1" bad "-0.1" good 6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real.insert(1, "0"); 6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (IsNaN(val)){ 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The JSON spec doesn't allow NaN and Infinity (since these are 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // objects in EcmaScript). Use strings instead. 6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real = "\"NaN\""; 6805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (val < 0) { 6815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real = "\"-Infinity\""; 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) real = "\"Infinity\""; 6844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) StringAppendF(out, "%s", real.c_str()); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TRACE_VALUE_TYPE_POINTER: 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // JSON only supports double and int numbers. 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So as not to lose bits from a 64-bit pointer, output as a hex string. 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringAppendF(out, "\"0x%" PRIx64 "\"", static_cast<uint64>( 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<intptr_t>( 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value.as_pointer))); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TRACE_VALUE_TYPE_STRING: 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TRACE_VALUE_TYPE_COPY_STRING: 6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EscapeJSONString(value.as_string ? value.as_string : "NULL", true, out); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Don't know how to print this value"; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceEvent::AppendAsJSON(std::string* out) const { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 time_int64 = timestamp_.ToInternalValue(); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id = TraceLog::GetInstance()->process_id(); 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Category group checked at category creation time. 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!strchr(name_, '"')); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringAppendF(out, 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 "," 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "\"ph\":\"%c\",\"name\":\"%s\",\"args\":{", 713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TraceLog::GetCategoryGroupName(category_group_enabled_), 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_id, 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_id_, 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_int64, 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) phase_, 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name_); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Output argument names and values, stop at first NULL argument name. 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i > 0) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out += ","; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out += "\""; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out += arg_names_[i]; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out += "\":"; 727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) convertable_values_[i]->AppendAsTraceFormat(out); 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AppendValueAsJSON(arg_types_[i], arg_values_[i], out); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out += "}"; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (phase_ == TRACE_EVENT_PHASE_COMPLETE) { 7368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int64 duration = duration_.ToInternalValue(); 7378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (duration != -1) 7388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StringAppendF(out, ",\"dur\":%" PRId64, duration); 739f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!thread_timestamp_.is_null()) { 740f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) int64 thread_duration = thread_duration_.ToInternalValue(); 741f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (thread_duration != -1) 742f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StringAppendF(out, ",\"tdur\":%" PRId64, thread_duration); 743f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 7448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 7458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Output tts if thread_timestamp is valid. 7473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!thread_timestamp_.is_null()) { 7483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int64 thread_time_int64 = thread_timestamp_.ToInternalValue(); 7493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) StringAppendF(out, ",\"tts\":%" PRId64, thread_time_int64); 7503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If id_ is set, print it out as a hex string so we don't loose any 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bits (it might be a 64-bit pointer). 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags_ & TRACE_EVENT_FLAG_HAS_ID) 755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringAppendF(out, ",\"id\":\"0x%" PRIx64 "\"", static_cast<uint64>(id_)); 756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Instant events also output their scope. 758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (phase_ == TRACE_EVENT_PHASE_INSTANT) { 759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char scope = '?'; 760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (flags_ & TRACE_EVENT_FLAG_SCOPE_MASK) { 761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case TRACE_EVENT_SCOPE_GLOBAL: 762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scope = TRACE_EVENT_SCOPE_NAME_GLOBAL; 763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case TRACE_EVENT_SCOPE_PROCESS: 766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scope = TRACE_EVENT_SCOPE_NAME_PROCESS; 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case TRACE_EVENT_SCOPE_THREAD: 770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scope = TRACE_EVENT_SCOPE_NAME_THREAD; 771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringAppendF(out, ",\"s\":\"%c\"", scope); 774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out += "}"; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TraceEvent::AppendPrettyPrinted(std::ostringstream* out) const { 7807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *out << name_ << "["; 7817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *out << TraceLog::GetCategoryGroupName(category_group_enabled_); 7827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *out << "]"; 7837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (arg_names_[0]) { 7847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *out << ", {"; 7857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (int i = 0; i < kTraceMaxNumArgs && arg_names_[i]; ++i) { 7867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (i > 0) 7877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *out << ", "; 7887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *out << arg_names_[i] << ":"; 7897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string value_as_text; 7907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (arg_types_[i] == TRACE_VALUE_TYPE_CONVERTABLE) 7927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch convertable_values_[i]->AppendAsTraceFormat(&value_as_text); 7937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else 7947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AppendValueAsJSON(arg_types_[i], arg_values_[i], &value_as_text); 7957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *out << value_as_text; 7977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 7987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch *out << "}"; 7997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 8007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 8017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceResultBuffer 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceResultBuffer::OutputCallback 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceResultBuffer::SimpleOutput::GetCallback() { 8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Bind(&SimpleOutput::Append, Unretained(this)); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceResultBuffer::SimpleOutput::Append( 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& json_trace_output) { 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) json_output += json_trace_output; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceResultBuffer::TraceResultBuffer() : append_comma_(false) { 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceResultBuffer::~TraceResultBuffer() { 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceResultBuffer::SetOutputCallback( 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OutputCallback& json_chunk_callback) { 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_callback_ = json_chunk_callback; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceResultBuffer::Start() { 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append_comma_ = false; 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_callback_.Run("["); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceResultBuffer::AddFragment(const std::string& trace_fragment) { 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (append_comma_) 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_callback_.Run(","); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) append_comma_ = true; 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_callback_.Run(trace_fragment); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceResultBuffer::Finish() { 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_callback_.Run("]"); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 8472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TraceSamplingThread 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 8492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 8502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceBucketData; 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef base::Callback<void(TraceBucketData*)> TraceSampleCallback; 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceBucketData { 8542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceBucketData(base::subtle::AtomicWord* bucket, 8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceSampleCallback callback); 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~TraceBucketData(); 8592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_API_ATOMIC_WORD* bucket; 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* bucket_name; 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceSampleCallback callback; 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This object must be created on the IO thread. 8662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TraceSamplingThread : public PlatformThread::Delegate { 8672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 8682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceSamplingThread(); 8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~TraceSamplingThread(); 8702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Implementation of PlatformThread::Delegate: 8722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void ThreadMain() OVERRIDE; 8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static void DefaultSamplingCallback(TraceBucketData* bucekt_data); 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Stop(); 877f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void WaitSamplingEventForTesting(); 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class TraceLog; 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void GetSamples(); 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Not thread-safe. Once the ThreadMain has been called, this can no longer 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be called. 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RegisterSampleBucket(TRACE_EVENT_API_ATOMIC_WORD* bucket, 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* const name, 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceSampleCallback callback); 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Splits a combined "category\0name" into the two component parts. 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void ExtractCategoryAndName(const char* combined, 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** category, 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** name); 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<TraceBucketData> sample_buckets_; 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool thread_running_; 894f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CancellationFlag cancellation_flag_; 895f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WaitableEvent waitable_event_for_testing_; 8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TraceSamplingThread::TraceSamplingThread() 900f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : thread_running_(false), 901f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) waitable_event_for_testing_(false, false) { 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TraceSamplingThread::~TraceSamplingThread() { 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TraceSamplingThread::ThreadMain() { 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PlatformThread::SetName("Sampling Thread"); 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) thread_running_ = true; 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kSamplingFrequencyMicroseconds = 1000; 911f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) while (!cancellation_flag_.IsSet()) { 9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PlatformThread::Sleep( 9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TimeDelta::FromMicroseconds(kSamplingFrequencyMicroseconds)); 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSamples(); 915f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) waitable_event_for_testing_.Signal(); 9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 9204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceSamplingThread::DefaultSamplingCallback( 9214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TraceBucketData* bucket_data) { 9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_API_ATOMIC_WORD category_and_name = 9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_API_ATOMIC_LOAD(*bucket_data->bucket); 9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!category_and_name) 9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* const combined = 9272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<const char* const>(category_and_name); 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group; 9292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name; 930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ExtractCategoryAndName(combined, &category_group, &name); 9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_API_ADD_TRACE_EVENT(TRACE_EVENT_PHASE_SAMPLE, 932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TraceLog::GetCategoryGroupEnabled(category_group), 933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) name, 0, 0, NULL, NULL, NULL, NULL, 0); 9342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TraceSamplingThread::GetSamples() { 9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < sample_buckets_.size(); ++i) { 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceBucketData* bucket_data = &sample_buckets_[i]; 9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bucket_data->callback.Run(bucket_data); 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TraceSamplingThread::RegisterSampleBucket( 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TRACE_EVENT_API_ATOMIC_WORD* bucket, 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* const name, 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceSampleCallback callback) { 947f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Access to sample_buckets_ doesn't cause races with the sampling thread 948f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // that uses the sample_buckets_, because it is guaranteed that 949f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // RegisterSampleBucket is called before the sampling thread is created. 9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!thread_running_); 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sample_buckets_.push_back(TraceBucketData(bucket, name, callback)); 9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TraceSamplingThread::ExtractCategoryAndName(const char* combined, 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** category, 9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** name) { 9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *category = combined; 9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *name = &combined[strlen(combined) + 1]; 9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TraceSamplingThread::Stop() { 963f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) cancellation_flag_.Set(); 9642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 966f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void TraceSamplingThread::WaitSamplingEventForTesting() { 967f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) waitable_event_for_testing_.Wait(); 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TraceBucketData::TraceBucketData(base::subtle::AtomicWord* bucket, 9712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 9722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TraceSampleCallback callback) 9732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : bucket(bucket), 9742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bucket_name(name), 9752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback(callback) { 9762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TraceBucketData::~TraceBucketData() { 9792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 9835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// TraceOptions 9845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// 9855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 9865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 9876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool TraceOptions::SetFromString(const std::string& options_string) { 9886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) record_mode = RECORD_UNTIL_FULL; 9896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) enable_sampling = false; 9906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) enable_systrace = false; 9916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 9925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<std::string> split; 9935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<std::string>::iterator iter; 9945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::SplitString(options_string, ',', &split); 9955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (iter = split.begin(); iter != split.end(); ++iter) { 9965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (*iter == kRecordUntilFull) { 9975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) record_mode = RECORD_UNTIL_FULL; 9985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (*iter == kRecordContinuously) { 9995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) record_mode = RECORD_CONTINUOUSLY; 10005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (*iter == kTraceToConsole) { 10015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) record_mode = ECHO_TO_CONSOLE; 10026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else if (*iter == kRecordAsMuchAsPossible) { 10036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) record_mode = RECORD_AS_MUCH_AS_POSSIBLE; 10045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (*iter == kEnableSampling) { 10055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) enable_sampling = true; 10065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (*iter == kEnableSystrace) { 10075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) enable_systrace = true; 10085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 10096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 10105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 10115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 10126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return true; 10135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 10145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)std::string TraceOptions::ToString() const { 10165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string ret; 10175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (record_mode) { 10185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case RECORD_UNTIL_FULL: 10195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret = kRecordUntilFull; 10205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 10215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case RECORD_CONTINUOUSLY: 10225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret = kRecordContinuously; 10235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 10245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case ECHO_TO_CONSOLE: 10255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret = kTraceToConsole; 10265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 10276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) case RECORD_AS_MUCH_AS_POSSIBLE: 10286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ret = kRecordAsMuchAsPossible; 10296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) break; 10305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) default: 10315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 10325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 10335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (enable_sampling) 10345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret = ret + "," + kEnableSampling; 10355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (enable_systrace) 10365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret = ret + "," + kEnableSystrace; 10375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ret; 10385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 10395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 10415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TraceLog 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//////////////////////////////////////////////////////////////////////////////// 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 104658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class TraceLog::ThreadLocalEventBuffer 104758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : public MessageLoop::DestructionObserver { 104858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public: 104958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ThreadLocalEventBuffer(TraceLog* trace_log); 105058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual ~ThreadLocalEventBuffer(); 105158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1052a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TraceEvent* AddTraceEvent(TraceEventHandle* handle); 10534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 105458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) void ReportOverhead(const TimeTicks& event_timestamp, 1055a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const TimeTicks& event_thread_timestamp); 10564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* GetEventByHandle(TraceEventHandle handle) { 10588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!chunk_ || handle.chunk_seq != chunk_->seq() || 10598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) handle.chunk_index != chunk_index_) 10608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return NULL; 10618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 10628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return chunk_->GetEventAt(handle.event_index); 10634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 10644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 10654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int generation() const { return generation_; } 106658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 106758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private: 106858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // MessageLoop::DestructionObserver 106958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void WillDestroyCurrentMessageLoop() OVERRIDE; 107058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void FlushWhileLocked(); 107258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 10734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void CheckThisIsCurrentBuffer() const { 107458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(trace_log_->thread_local_event_buffer_.Get() == this); 107558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 107658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 107758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Since TraceLog is a leaky singleton, trace_log_ will always be valid 107858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // as long as the thread exists. 107958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TraceLog* trace_log_; 10804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBufferChunk> chunk_; 10814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t chunk_index_; 108258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) int event_count_; 108358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TimeDelta overhead_; 10844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int generation_; 108558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 108658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ThreadLocalEventBuffer); 108758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 108858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 108958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TraceLog::ThreadLocalEventBuffer::ThreadLocalEventBuffer(TraceLog* trace_log) 109058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : trace_log_(trace_log), 10914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunk_index_(0), 10924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) event_count_(0), 10934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) generation_(trace_log->generation()) { 109458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // ThreadLocalEventBuffer is created only if the thread has a message loop, so 109558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // the following message_loop won't be NULL. 109658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) MessageLoop* message_loop = MessageLoop::current(); 109758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) message_loop->AddDestructionObserver(this); 109858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 109958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AutoLock lock(trace_log->lock_); 110058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) trace_log->thread_message_loops_.insert(message_loop); 110158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 110258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 110358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TraceLog::ThreadLocalEventBuffer::~ThreadLocalEventBuffer() { 110458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CheckThisIsCurrentBuffer(); 110558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) MessageLoop::current()->RemoveDestructionObserver(this); 110658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 110758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Zero event_count_ happens in either of the following cases: 110858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // - no event generated for the thread; 110958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // - the thread has no message loop; 111058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // - trace_event_overhead is disabled. 111158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (event_count_) { 1112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InitializeMetadataEvent(AddTraceEvent(NULL), 11134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static_cast<int>(base::PlatformThread::CurrentId()), 11144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "overhead", "average_overhead", 11154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) overhead_.InMillisecondsF() / event_count_); 11164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 11174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 111858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 111958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AutoLock lock(trace_log_->lock_); 11204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FlushWhileLocked(); 112158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) trace_log_->thread_message_loops_.erase(MessageLoop::current()); 112258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 112358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) trace_log_->thread_local_event_buffer_.Set(NULL); 112458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 112558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TraceEvent* TraceLog::ThreadLocalEventBuffer::AddTraceEvent( 11278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEventHandle* handle) { 112858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CheckThisIsCurrentBuffer(); 11294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (chunk_ && chunk_->IsFull()) { 11314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AutoLock lock(trace_log_->lock_); 11324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FlushWhileLocked(); 11334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunk_.reset(); 11344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 11354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!chunk_) { 113658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AutoLock lock(trace_log_->lock_); 11374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunk_ = trace_log_->logged_events_->GetChunk(&chunk_index_); 1138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) trace_log_->CheckIfBufferIsFullWhileLocked(); 113958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 11404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!chunk_) 11414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 11424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 11438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) size_t event_index; 11448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* trace_event = chunk_->AddTraceEvent(&event_index); 11458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (trace_event && handle) 11461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MakeHandle(chunk_->seq(), chunk_index_, event_index, handle); 11471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 11488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return trace_event; 114958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 115058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 115158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TraceLog::ThreadLocalEventBuffer::ReportOverhead( 11524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TimeTicks& event_timestamp, 1153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const TimeTicks& event_thread_timestamp) { 115458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!g_category_group_enabled[g_category_trace_event_overhead]) 115558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 115658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CheckThisIsCurrentBuffer(); 11584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 115958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) event_count_++; 1160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TimeTicks thread_now = ThreadNow(); 11610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) TimeTicks now = trace_log_->OffsetNow(); 116258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TimeDelta overhead = now - event_timestamp; 116358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (overhead.InMicroseconds() >= kOverheadReportThresholdInMicroseconds) { 1164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TraceEvent* trace_event = AddTraceEvent(NULL); 11654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (trace_event) { 11664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) trace_event->Initialize( 11678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static_cast<int>(PlatformThread::CurrentId()), 11688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) event_timestamp, event_thread_timestamp, 11698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TRACE_EVENT_PHASE_COMPLETE, 11704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &g_category_group_enabled[g_category_trace_event_overhead], 11714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "overhead", 0, 0, NULL, NULL, NULL, NULL, 0); 1172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) trace_event->UpdateDuration(now, thread_now); 11734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 117458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 117558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) overhead_ += overhead; 117658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 117758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 117858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TraceLog::ThreadLocalEventBuffer::WillDestroyCurrentMessageLoop() { 117958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) delete this; 118058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 118158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceLog::ThreadLocalEventBuffer::FlushWhileLocked() { 11831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!chunk_) 11841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 11851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 118658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) trace_log_->lock_.AssertAcquired(); 11871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (trace_log_->CheckGeneration(generation_)) { 11885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Return the chunk to the buffer only if the generation matches. 11891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) trace_log_->logged_events_->ReturnChunk(chunk_index_, chunk_.Pass()); 11901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 11911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Otherwise this method may be called from the destructor, or TraceLog will 11921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // find the generation mismatch and delete this buffer soon. 119358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 119458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceLog* TraceLog::GetInstance() { 11977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return Singleton<TraceLog, LeakySingletonTraits<TraceLog> >::get(); 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceLog::TraceLog() 12015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : mode_(DISABLED), 1202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) num_traces_recorded_(0), 120358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) event_callback_(0), 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispatching_to_observer_list_(false), 12057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process_sort_index_(0), 120658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) process_id_hash_(0), 120758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) process_id_(0), 120858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) watch_category_(0), 12095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) trace_options_(kInternalRecordUntilFull), 1210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sampling_thread_handle_(0), 121158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) category_filter_(CategoryFilter::kDefaultCategoryFilterString), 1212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_callback_category_filter_( 1213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CategoryFilter::kDefaultCategoryFilterString), 12144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_shared_chunk_index_(0), 12154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) generation_(0) { 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trace is enabled or disabled on one thread while other threads are 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // accessing the enabled flag. We don't care whether edge-case events are 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // traced or not, so we allow races on the enabled flag to keep the trace 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // macros fast. 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jbates): ANNOTATE_BENIGN_RACE_SIZED crashes windows TSAN bots: 1221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // ANNOTATE_BENIGN_RACE_SIZED(g_category_group_enabled, 1222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // sizeof(g_category_group_enabled), 1223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // "trace_event category enabled"); 1224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int i = 0; i < MAX_CATEGORY_GROUPS; ++i) { 1225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ANNOTATE_BENIGN_RACE(&g_category_group_enabled[i], 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "trace_event category enabled"); 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_NACL) // NaCl shouldn't expose the process id. 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetProcessID(0); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 12312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetProcessID(static_cast<int>(GetCurrentProcId())); 12327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 12337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // NaCl also shouldn't access the command line. 12347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (CommandLine::InitializedForCurrentProcess() && 12357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CommandLine::ForCurrentProcess()->HasSwitch(switches::kTraceToConsole)) { 12365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string filter = CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 12375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switches::kTraceToConsole); 12385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (filter.empty()) { 12395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) filter = kEchoToConsoleCategoryFilter; 12405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 12415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) filter.append(","); 12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) filter.append(kEchoToConsoleCategoryFilter); 12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(ERROR) << "Start " << switches::kTraceToConsole 12465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " with CategoryFilter '" << filter << "'."; 12475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SetEnabled(CategoryFilter(filter), 12485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) RECORDING_MODE, 12495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TraceOptions(ECHO_TO_CONSOLE)); 12507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logged_events_.reset(CreateTraceBuffer()); 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TraceLog::~TraceLog() { 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const unsigned char* TraceLog::GetCategoryGroupEnabled( 1260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group) { 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceLog* tracelog = GetInstance(); 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!tracelog) { 1263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!g_category_group_enabled[g_category_already_shutdown]); 1264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return &g_category_group_enabled[g_category_already_shutdown]; 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return tracelog->GetCategoryGroupEnabledInternal(category_group); 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char* TraceLog::GetCategoryGroupName( 1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled) { 1271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Calculate the index of the category group by finding 1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // category_group_enabled in g_category_group_enabled array. 1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uintptr_t category_begin = 1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reinterpret_cast<uintptr_t>(g_category_group_enabled); 1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uintptr_t category_ptr = reinterpret_cast<uintptr_t>(category_group_enabled); 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(category_ptr >= category_begin && 1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category_ptr < reinterpret_cast<uintptr_t>( 1278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) g_category_group_enabled + MAX_CATEGORY_GROUPS)) << 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "out of bounds category pointer"; 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uintptr_t category_index = 1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (category_ptr - category_begin) / sizeof(g_category_group_enabled[0]); 1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return g_category_groups[category_index]; 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid TraceLog::UpdateCategoryGroupEnabledFlag(size_t category_index) { 1286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) unsigned char enabled_flag = 0; 1287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* category_group = g_category_groups[category_index]; 12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (mode_ == RECORDING_MODE && 12895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) category_filter_.IsCategoryGroupEnabled(category_group)) 1290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enabled_flag |= ENABLED_FOR_RECORDING; 12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else if (mode_ == MONITORING_MODE && 12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) category_filter_.IsCategoryGroupEnabled(category_group)) 12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enabled_flag |= ENABLED_FOR_MONITORING; 1294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (event_callback_ && 1295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_callback_category_filter_.IsCategoryGroupEnabled(category_group)) 1296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) enabled_flag |= ENABLED_FOR_EVENT_CALLBACK; 1297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) g_category_group_enabled[category_index] = enabled_flag; 129890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 129990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1300bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid TraceLog::UpdateCategoryGroupEnabledFlags() { 1301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); 1302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < category_index; i++) 1303bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch UpdateCategoryGroupEnabledFlag(i); 1304bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 1305bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 13065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TraceLog::UpdateSyntheticDelaysFromCategoryFilter() { 13075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResetTraceEventSyntheticDelays(); 13085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const CategoryFilter::StringList& delays = 13095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) category_filter_.GetSyntheticDelayValues(); 13105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CategoryFilter::StringList::const_iterator ci; 13115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ci = delays.begin(); ci != delays.end(); ++ci) { 13125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringTokenizer tokens(*ci, ";"); 13135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!tokens.GetNext()) 13145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 13155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TraceEventSyntheticDelay* delay = 13165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TraceEventSyntheticDelay::Lookup(tokens.token()); 13175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (tokens.GetNext()) { 13185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string token = tokens.token(); 13195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char* duration_end; 13205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) double target_duration = strtod(token.c_str(), &duration_end); 13215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (duration_end != token.c_str()) { 13225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delay->SetTargetDuration( 13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TimeDelta::FromMicroseconds(target_duration * 1e6)); 13245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (token == "static") { 13255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delay->SetMode(TraceEventSyntheticDelay::STATIC); 13265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (token == "oneshot") { 13275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delay->SetMode(TraceEventSyntheticDelay::ONE_SHOT); 13285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (token == "alternating") { 13295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delay->SetMode(TraceEventSyntheticDelay::ALTERNATING); 13305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 13345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const unsigned char* TraceLog::GetCategoryGroupEnabledInternal( 1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group) { 1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!strchr(category_group, '"')) << 1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "Category groups may not contain double quote"; 1339a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // The g_category_groups is append only, avoid using a lock for the fast path. 1340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t current_category_index = base::subtle::Acquire_Load(&g_category_index); 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Search for pre-existing category group. 1343116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < current_category_index; ++i) { 1344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (strcmp(g_category_groups[i], category_group) == 0) { 1345a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return &g_category_group_enabled[i]; 13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1349a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch unsigned char* category_group_enabled = NULL; 1350a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // This is the slow path: the lock is not held in the case above, so more 1351a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // than one thread could have reached here trying to add the same category. 1352a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Only hold to lock when actually appending a new category, and 1353a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // check the categories groups again. 1354a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch AutoLock lock(lock_); 1355116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t category_index = base::subtle::Acquire_Load(&g_category_index); 1356116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = 0; i < category_index; ++i) { 1357a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (strcmp(g_category_groups[i], category_group) == 0) { 1358a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return &g_category_group_enabled[i]; 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1361a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 1362a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Create a new category group. 1363a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(category_index < MAX_CATEGORY_GROUPS) << 1364a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch "must increase MAX_CATEGORY_GROUPS"; 1365a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (category_index < MAX_CATEGORY_GROUPS) { 1366a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Don't hold on to the category_group pointer, so that we can create 1367a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // category groups with strings not known at compile time (this is 1368a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // required by SetWatchEvent). 1369a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const char* new_group = strdup(category_group); 1370a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ANNOTATE_LEAKING_OBJECT_PTR(new_group); 1371a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch g_category_groups[category_index] = new_group; 1372a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch DCHECK(!g_category_group_enabled[category_index]); 1373a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Note that if both included and excluded patterns in the 1374a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // CategoryFilter are empty, we exclude nothing, 1375a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // thereby enabling this category group. 1376a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch UpdateCategoryGroupEnabledFlag(category_index); 1377a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch category_group_enabled = &g_category_group_enabled[category_index]; 1378a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Update the max index now. 1379a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::subtle::Release_Store(&g_category_index, category_index + 1); 1380a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 1381a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch category_group_enabled = 1382a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &g_category_group_enabled[g_category_categories_exhausted]; 1383a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 1384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return category_group_enabled; 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TraceLog::GetKnownCategoryGroups( 1388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string>* category_groups) { 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(lock_); 139058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) category_groups->push_back( 139158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) g_category_groups[g_category_trace_event_overhead]); 1392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch size_t category_index = base::subtle::NoBarrier_Load(&g_category_index); 1393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (size_t i = g_num_builtin_categories; i < category_index; i++) 1394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category_groups->push_back(g_category_groups[i]); 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TraceLog::SetEnabled(const CategoryFilter& category_filter, 13985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Mode mode, 13995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const TraceOptions& options) { 14007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::vector<EnabledStateObserver*> observer_list; 14017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { 14027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(lock_); 14032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 140458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Can't enable tracing when Flush() is in progress. 140558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!flush_message_loop_proxy_.get()); 140658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) InternalTraceOptions new_options = 14085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetInternalOptionsFromTraceOptions(options); 14095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 14105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) InternalTraceOptions old_options = trace_options(); 141158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 14125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsEnabled()) { 14135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (new_options != old_options) { 1414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DLOG(ERROR) << "Attempting to re-enable tracing with a different " 14157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) << "set of options."; 14167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 14177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 14185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (mode != mode_) { 1419a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DLOG(ERROR) << "Attempting to re-enable tracing with a different mode."; 14205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 14215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 14227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) category_filter_.Merge(category_filter); 1423bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch UpdateCategoryGroupEnabledFlags(); 14247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (dispatching_to_observer_list_) { 1428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DLOG(ERROR) << 1429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "Cannot manipulate TraceLog::Enabled state from an observer."; 1430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 1431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 1432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mode_ = mode; 1434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (new_options != old_options) { 14365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) subtle::NoBarrier_Store(&trace_options_, new_options); 14375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UseNextTraceBuffer(); 14387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) num_traces_recorded_++; 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) category_filter_ = CategoryFilter(category_filter); 1443bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch UpdateCategoryGroupEnabledFlags(); 14445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateSyntheticDelaysFromCategoryFilter(); 1445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 14465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (new_options & kInternalEnableSampling) { 14477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sampling_thread_.reset(new TraceSamplingThread); 14487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sampling_thread_->RegisterSampleBucket( 14497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &g_trace_state[0], 14507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "bucket0", 14514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Bind(&TraceSamplingThread::DefaultSamplingCallback)); 14527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sampling_thread_->RegisterSampleBucket( 14537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &g_trace_state[1], 14547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "bucket1", 14554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Bind(&TraceSamplingThread::DefaultSamplingCallback)); 14567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) sampling_thread_->RegisterSampleBucket( 14577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &g_trace_state[2], 14587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) "bucket2", 14594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Bind(&TraceSamplingThread::DefaultSamplingCallback)); 14607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!PlatformThread::Create( 14617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 0, sampling_thread_.get(), &sampling_thread_handle_)) { 14627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(false) << "failed to create thread"; 14637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 14647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dispatching_to_observer_list_ = true; 14677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) observer_list = enabled_state_observer_list_; 14687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 14697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Notify observers outside the lock in case they trigger trace events. 14707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (size_t i = 0; i < observer_list.size(); ++i) 14717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) observer_list[i]->OnTraceLogEnabled(); 14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { 14747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) AutoLock lock(lock_); 14757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) dispatching_to_observer_list_ = false; 14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TraceLog::InternalTraceOptions TraceLog::GetInternalOptionsFromTraceOptions( 14805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const TraceOptions& options) { 14815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) InternalTraceOptions ret = 14825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) options.enable_sampling ? kInternalEnableSampling : kInternalNone; 14835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) switch (options.record_mode) { 14845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case RECORD_UNTIL_FULL: 14855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ret | kInternalRecordUntilFull; 14865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case RECORD_CONTINUOUSLY: 14875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ret | kInternalRecordContinuously; 14885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case ECHO_TO_CONSOLE: 14895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ret | kInternalEchoToConsole; 14906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) case RECORD_AS_MUCH_AS_POSSIBLE: 14916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return ret | kInternalRecordAsMuchAsPossible; 14925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 14935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 14945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return kInternalNone; 14955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 14965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)CategoryFilter TraceLog::GetCurrentCategoryFilter() { 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(lock_); 1499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return category_filter_; 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TraceOptions TraceLog::GetCurrentTraceOptions() const { 15035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TraceOptions ret; 15045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) InternalTraceOptions option = trace_options(); 15055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret.enable_sampling = (option & kInternalEnableSampling) != 0; 15065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (option & kInternalRecordUntilFull) 15075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret.record_mode = RECORD_UNTIL_FULL; 15085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else if (option & kInternalRecordContinuously) 15095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret.record_mode = RECORD_CONTINUOUSLY; 15105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else if (option & kInternalEchoToConsole) 15115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ret.record_mode = ECHO_TO_CONSOLE; 15126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else if (option & kInternalRecordAsMuchAsPossible) 15136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ret.record_mode = RECORD_AS_MUCH_AS_POSSIBLE; 15145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 15155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED(); 15165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ret; 15175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 15185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceLog::SetDisabled() { 1520a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoLock lock(lock_); 1521a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetDisabledWhileLocked(); 1522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1524a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TraceLog::SetDisabledWhileLocked() { 1525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) lock_.AssertAcquired(); 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsEnabled()) 1528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 1529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (dispatching_to_observer_list_) { 1531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DLOG(ERROR) 1532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) << "Cannot manipulate TraceLog::Enabled state from an observer."; 1533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 1534a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 15357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 15365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mode_ = DISABLED; 15377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1538a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (sampling_thread_.get()) { 1539a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Stop the sampling thread. 1540a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sampling_thread_->Stop(); 1541a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) lock_.Release(); 1542a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) PlatformThread::Join(sampling_thread_handle_); 1543a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) lock_.Acquire(); 1544a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sampling_thread_handle_ = PlatformThreadHandle(); 1545a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) sampling_thread_.reset(); 15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1548a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) category_filter_.Clear(); 1549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) subtle::NoBarrier_Store(&watch_category_, 0); 1550a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) watch_event_name_ = ""; 1551a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) UpdateCategoryGroupEnabledFlags(); 1552a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddMetadataEventsWhileLocked(); 1553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1554a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dispatching_to_observer_list_ = true; 1555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::vector<EnabledStateObserver*> observer_list = 1556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) enabled_state_observer_list_; 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) { 1559a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Dispatch to observers outside the lock in case the observer triggers a 1560a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // trace event. 1561a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoUnlock unlock(lock_); 1562a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) for (size_t i = 0; i < observer_list.size(); ++i) 1563a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) observer_list[i]->OnTraceLogDisabled(); 15647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) dispatching_to_observer_list_ = false; 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)int TraceLog::GetNumTracesRecorded() { 1569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AutoLock lock(lock_); 15705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsEnabled()) 1571868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return -1; 1572868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return num_traces_recorded_; 1573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1574868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 15757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TraceLog::AddEnabledStateObserver(EnabledStateObserver* listener) { 15767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) enabled_state_observer_list_.push_back(listener); 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TraceLog::RemoveEnabledStateObserver(EnabledStateObserver* listener) { 15807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::vector<EnabledStateObserver*>::iterator it = 15817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::find(enabled_state_observer_list_.begin(), 15827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) enabled_state_observer_list_.end(), 15837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) listener); 15847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (it != enabled_state_observer_list_.end()) 15857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) enabled_state_observer_list_.erase(it); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1588bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdochbool TraceLog::HasEnabledStateObserver(EnabledStateObserver* listener) const { 1589bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::vector<EnabledStateObserver*>::const_iterator it = 1590bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::find(enabled_state_observer_list_.begin(), 1591bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch enabled_state_observer_list_.end(), 1592bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch listener); 1593bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch return it != enabled_state_observer_list_.end(); 1594bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 1595bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)float TraceLog::GetBufferPercentFull() const { 1597a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoLock lock(lock_); 15983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return static_cast<float>(static_cast<double>(logged_events_->Size()) / 15993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) logged_events_->Capacity()); 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1602a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool TraceLog::BufferIsFull() const { 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(lock_); 1604a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return logged_events_->IsFull(); 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TraceBuffer* TraceLog::CreateTraceBuffer() { 16085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) InternalTraceOptions options = trace_options(); 16095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (options & kInternalRecordContinuously) 16104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new TraceBufferRingBuffer(kTraceEventRingBufferChunks); 16115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else if ((options & kInternalEnableSampling) && mode_ == MONITORING_MODE) 16124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new TraceBufferRingBuffer(kMonitorTraceEventBufferChunks); 16135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else if (options & kInternalEchoToConsole) 16141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return new TraceBufferRingBuffer(kEchoToConsoleTraceEventBufferChunks); 16156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else if (options & kInternalRecordAsMuchAsPossible) 16166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return CreateTraceBufferVectorOfSize(kTraceEventVectorBigBufferChunks); 16175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return CreateTraceBufferVectorOfSize(kTraceEventVectorBufferChunks); 16185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 16195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TraceBuffer* TraceLog::CreateTraceBufferVectorOfSize(size_t max_chunks) { 16215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return new TraceBufferVector(max_chunks); 16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TraceEvent* TraceLog::AddEventToThreadSharedChunkWhileLocked( 1625a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TraceEventHandle* handle, bool check_buffer_is_full) { 162658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) lock_.AssertAcquired(); 16274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 16284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (thread_shared_chunk_ && thread_shared_chunk_->IsFull()) { 16294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logged_events_->ReturnChunk(thread_shared_chunk_index_, 16304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_shared_chunk_.Pass()); 16314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 16324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 16334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!thread_shared_chunk_) { 16344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_shared_chunk_ = logged_events_->GetChunk( 16354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &thread_shared_chunk_index_); 1636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (check_buffer_is_full) 1637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) CheckIfBufferIsFullWhileLocked(); 16384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 16394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!thread_shared_chunk_) 16404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return NULL; 16414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 16428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) size_t event_index; 16438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* trace_event = thread_shared_chunk_->AddTraceEvent(&event_index); 16448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (trace_event && handle) { 16451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MakeHandle(thread_shared_chunk_->seq(), thread_shared_chunk_index_, 16461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) event_index, handle); 16478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 16488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return trace_event; 164958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 165058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1651a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void TraceLog::CheckIfBufferIsFullWhileLocked() { 165258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) lock_.AssertAcquired(); 16535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (logged_events_->IsFull()) { 16545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (buffer_limit_reached_timestamp_.is_null()) { 16555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buffer_limit_reached_timestamp_ = OffsetNow(); 16565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1657a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetDisabledWhileLocked(); 16585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 165958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 166058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void TraceLog::SetEventCallbackEnabled(const CategoryFilter& category_filter, 1662f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EventCallback cb) { 1663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AutoLock lock(lock_); 166458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::NoBarrier_Store(&event_callback_, 166558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) reinterpret_cast<subtle::AtomicWord>(cb)); 1666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_callback_category_filter_ = category_filter; 1667f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateCategoryGroupEnabledFlags(); 16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1670f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void TraceLog::SetEventCallbackDisabled() { 1671f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) AutoLock lock(lock_); 1672f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) subtle::NoBarrier_Store(&event_callback_, 0); 1673f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UpdateCategoryGroupEnabledFlags(); 1674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 1675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 167658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Flush() works as the following: 167758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// 1. Flush() is called in threadA whose message loop is saved in 167858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// flush_message_loop_proxy_; 167958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// 2. If thread_message_loops_ is not empty, threadA posts task to each message 168058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// loop to flush the thread local buffers; otherwise finish the flush; 168158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// 3. FlushCurrentThread() deletes the thread local event buffer: 168258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// - The last batch of events of the thread are flushed into the main buffer; 168358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// - The message loop will be removed from thread_message_loops_; 168458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// If this is the last message loop, finish the flush; 168558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// 4. If any thread hasn't finish its flush in time, finish the flush. 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceLog::Flush(const TraceLog::OutputCallback& cb) { 168758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (IsEnabled()) { 168858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Can't flush when tracing is enabled because otherwise PostTask would 1689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // - generate more trace events; 1690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // - deschedule the calling thread on some platforms causing inaccurate 169158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // timing of the trace events. 169258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<RefCountedString> empty_result = new RefCountedString; 169358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!cb.is_null()) 169458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) cb.Run(empty_result, false); 1695d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) LOG(WARNING) << "Ignored TraceLog::Flush called when tracing is enabled"; 169658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 169758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 169858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 16994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int generation = this->generation(); 17001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Copy of thread_message_loops_ to be used without locking. 17011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::vector<scoped_refptr<SingleThreadTaskRunner> > 17021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci thread_message_loop_task_runners; 170358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 170458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AutoLock lock(lock_); 170558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!flush_message_loop_proxy_.get()); 170658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) flush_message_loop_proxy_ = MessageLoopProxy::current(); 170758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!thread_message_loops_.size() || flush_message_loop_proxy_.get()); 170858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) flush_output_callback_ = cb; 170958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (thread_shared_chunk_) { 17114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logged_events_->ReturnChunk(thread_shared_chunk_index_, 17124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_shared_chunk_.Pass()); 17134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 17144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 171558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (thread_message_loops_.size()) { 171658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) for (hash_set<MessageLoop*>::const_iterator it = 171758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) thread_message_loops_.begin(); 171858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) it != thread_message_loops_.end(); ++it) { 17191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci thread_message_loop_task_runners.push_back((*it)->task_runner()); 172058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 17211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 17221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 17231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 17241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (thread_message_loop_task_runners.size()) { 17251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (size_t i = 0; i < thread_message_loop_task_runners.size(); ++i) { 17261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci thread_message_loop_task_runners[i]->PostTask( 172758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FROM_HERE, 17281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Bind(&TraceLog::FlushCurrentThread, Unretained(this), generation)); 172958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 17301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flush_message_loop_proxy_->PostDelayedTask( 17311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 17321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation), 17331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs)); 17341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 173558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 173658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FinishFlush(generation); 173858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 173958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceLog::ConvertTraceEventsToTraceFormat( 17414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBuffer> logged_events, 17424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TraceLog::OutputCallback& flush_output_callback) { 174358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 174458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (flush_output_callback.is_null()) 174558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 174758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The callback need to be called at least once even if there is no events 174858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // to let the caller know the completion of flush. 17494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool has_more_events = true; 175058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) do { 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<RefCountedString> json_events_str_ptr = 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new RefCountedString(); 17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < kTraceEventBatchChunks; ++i) { 17554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TraceBufferChunk* chunk = logged_events->NextChunk(); 17564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!chunk) { 17574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) has_more_events = false; 17584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 17594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 17604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t j = 0; j < chunk->size(); ++j) { 17614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (i > 0 || j > 0) 17624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) json_events_str_ptr->data().append(","); 17634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) chunk->GetEventAt(j)->AppendAsJSON(&(json_events_str_ptr->data())); 17644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 176758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) flush_output_callback.Run(json_events_str_ptr, has_more_events); 176858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } while (has_more_events); 176958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 177058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 17714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceLog::FinishFlush(int generation) { 17724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBuffer> previous_logged_events; 17734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OutputCallback flush_output_callback; 17744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 17754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!CheckGeneration(generation)) 17764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 17774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 17784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 17794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AutoLock lock(lock_); 17804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 17814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) previous_logged_events.swap(logged_events_); 17825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UseNextTraceBuffer(); 17834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_message_loops_.clear(); 17844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 17854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) flush_message_loop_proxy_ = NULL; 17864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) flush_output_callback = flush_output_callback_; 17874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) flush_output_callback_.Reset(); 17884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 17894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 17904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), 17914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) flush_output_callback); 17924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 17934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 179458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Run in each thread holding a local event buffer. 17954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceLog::FlushCurrentThread(int generation) { 179658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 179758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AutoLock lock(lock_); 17981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) { 179958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // This is late. The corresponding flush has finished. 180058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 180158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 180358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 18048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // This will flush the thread local buffer. 180558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) delete thread_local_event_buffer_.Get(); 180658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 18071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AutoLock lock(lock_); 18081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get() || 18091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) thread_message_loops_.size()) 18101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 18114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 18124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) flush_message_loop_proxy_->PostTask( 18134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FROM_HERE, 18144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Bind(&TraceLog::FinishFlush, Unretained(this), generation)); 181558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 181658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 18174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceLog::OnFlushTimeout(int generation) { 181858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 181958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) AutoLock lock(lock_); 18201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!CheckGeneration(generation) || !flush_message_loop_proxy_.get()) { 182158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Flush has finished before timeout. 182258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 182358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 182458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 18258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(WARNING) << 18268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "The following threads haven't finished flush in time. " 18278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "If this happens stably for some thread, please call " 18288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop() from " 18298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) "the thread to avoid its trace events from being lost."; 18308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) for (hash_set<MessageLoop*>::const_iterator it = 18318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) thread_message_loops_.begin(); 18328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) it != thread_message_loops_.end(); ++it) { 18338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(WARNING) << "Thread: " << (*it)->thread_name(); 18348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 183558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 18364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FinishFlush(generation); 18374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 18384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 18394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceLog::FlushButLeaveBufferIntact( 18404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const TraceLog::OutputCallback& flush_output_callback) { 18414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_ptr<TraceBuffer> previous_logged_events; 18424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 18434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AutoLock lock(lock_); 18444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AddMetadataEventsWhileLocked(); 18454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (thread_shared_chunk_) { 18464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Return the chunk to the main buffer to flush the sampling data. 18474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) logged_events_->ReturnChunk(thread_shared_chunk_index_, 18484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_shared_chunk_.Pass()); 18494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 18504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) previous_logged_events = logged_events_->CloneForIteration().Pass(); 18514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } // release lock 18524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 18534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConvertTraceEventsToTraceFormat(previous_logged_events.Pass(), 18544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) flush_output_callback); 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TraceLog::UseNextTraceBuffer() { 18585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) logged_events_.reset(CreateTraceBuffer()); 18595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) subtle::NoBarrier_AtomicIncrement(&generation_, 1); 18605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thread_shared_chunk_.reset(); 18615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) thread_shared_chunk_index_ = 0; 18625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 18635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 18648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TraceEventHandle TraceLog::AddTraceEvent( 1865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char phase, 1866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 1867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* name, 1868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned long long id, 1869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int num_args, 1870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char** arg_names, 1871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* arg_types, 1872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned long long* arg_values, 18734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 1874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned char flags) { 18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime(); 18778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled, 18788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) name, id, thread_id, now, 18798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) num_args, arg_names, 18808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) arg_types, arg_values, 18818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) convertable_values, flags); 18822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TraceEventHandle TraceLog::AddTraceEventWithThreadIdAndTimestamp( 18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) char phase, 1886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category_group_enabled, 18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* name, 18882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned long long id, 18892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int thread_id, 18902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TimeTicks& timestamp, 18912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int num_args, 18922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char** arg_names, 18932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned char* arg_types, 18942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const unsigned long long* arg_values, 18954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<ConvertableToTraceFormat>* convertable_values, 18962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned char flags) { 18971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) TraceEventHandle handle = { 0, 0, 0 }; 18984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!*category_group_enabled) 18998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return handle; 19004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1901a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when 1902a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) -> 1903a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ... 1904a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (thread_is_in_trace_event_.Get()) 1905a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return handle; 1906a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1907a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_); 1908a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(name); 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (flags & TRACE_EVENT_FLAG_MANGLE_ID) 19122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) id ^= process_id_hash_; 19132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) TimeTicks now = OffsetTimestamp(timestamp); 191558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TimeTicks thread_now = ThreadNow(); 19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 191758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ThreadLocalEventBuffer* thread_local_event_buffer = NULL; 191858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // A ThreadLocalEventBuffer needs the message loop 191958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // - to know when the thread exits; 192058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // - to handle the final flush. 19218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // For a thread without a message loop or the message loop may be blocked, the 19228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // trace events will be added into the main buffer directly. 19238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!thread_blocks_message_loop_.Get() && MessageLoop::current()) { 192458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) thread_local_event_buffer = thread_local_event_buffer_.Get(); 19254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (thread_local_event_buffer && 19264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) !CheckGeneration(thread_local_event_buffer->generation())) { 19274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) delete thread_local_event_buffer; 19284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_local_event_buffer = NULL; 19294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 193058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!thread_local_event_buffer) { 193158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) thread_local_event_buffer = new ThreadLocalEventBuffer(this); 193258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) thread_local_event_buffer_.Set(thread_local_event_buffer); 193358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 193458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 193558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1936ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // Check and update the current thread name only if the event is for the 1937ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // current thread to avoid locks in most cases. 1938ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (thread_id == static_cast<int>(PlatformThread::CurrentId())) { 19392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* new_name = ThreadIdNameManager::GetInstance()-> 19402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetName(thread_id); 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the thread name has been set or changed since the previous 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call (if any), but don't bother if the new name is empty. Note this will 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not detect a thread name change within the same char* buffer address: we 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // favor common case performance over corner case correctness. 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_name != g_current_thread_name.Get().Get() && 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_name && *new_name) { 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_current_thread_name.Get().Set(new_name); 19482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoLock thread_info_lock(thread_info_lock_); 1950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) hash_map<int, std::string>::iterator existing_name = 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_names_.find(thread_id); 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing_name == thread_names_.end()) { 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a new thread id, and a new name. 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_names_[thread_id] = new_name; 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a thread id that we've seen before, but potentially with a 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // new name. 19592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<StringPiece> existing_names; 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tokenize(existing_name->second, ",", &existing_names); 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found = std::find(existing_names.begin(), 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_names.end(), 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_name) != existing_names.end(); 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found) { 1965a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (existing_names.size()) 1966a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) existing_name->second.push_back(','); 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) existing_name->second.append(new_name); 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1971ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1973a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string console_message; 19745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (*category_group_enabled & 19755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (ENABLED_FOR_RECORDING | ENABLED_FOR_MONITORING)) { 1976a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OptionalAutoLock lock(lock_); 1977a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1978a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TraceEvent* trace_event = NULL; 197958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (thread_local_event_buffer) { 1980a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) trace_event = thread_local_event_buffer->AddTraceEvent(&handle); 198158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 19824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) lock.EnsureAcquired(); 1983a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) trace_event = AddEventToThreadSharedChunkWhileLocked(&handle, true); 198458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 19857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 19864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (trace_event) { 19874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) trace_event->Initialize(thread_id, now, thread_now, phase, 19884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) category_group_enabled, name, id, 19894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) num_args, arg_names, arg_types, arg_values, 19904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) convertable_values, flags); 19918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 19928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_ANDROID) 19938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) trace_event->SendToATrace(); 19948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 19975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (trace_options() & kInternalEchoToConsole) { 1998a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) console_message = EventToConsoleMessage( 1999a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) phase == TRACE_EVENT_PHASE_COMPLETE ? TRACE_EVENT_PHASE_BEGIN : phase, 2000a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) timestamp, trace_event); 2001a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 20021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 20031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2004a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (console_message.size()) 2005a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(ERROR) << console_message; 2006a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 200758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (reinterpret_cast<const unsigned char*>(subtle::NoBarrier_Load( 200858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) &watch_category_)) == category_group_enabled) { 2009a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool event_name_matches; 2010a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) WatchEventCallback watch_event_callback_copy; 2011a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) { 2012a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoLock lock(lock_); 2013a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) event_name_matches = watch_event_name_ == name; 2014a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) watch_event_callback_copy = watch_event_callback_; 2015a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 2016a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (event_name_matches) { 2017a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!watch_event_callback_copy.is_null()) 2018a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) watch_event_callback_copy.Run(); 2019a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 202058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (*category_group_enabled & ENABLED_FOR_EVENT_CALLBACK) { 2023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EventCallback event_callback = reinterpret_cast<EventCallback>( 2024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) subtle::NoBarrier_Load(&event_callback_)); 2025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (event_callback) { 2026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_callback(now, 2027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) phase == TRACE_EVENT_PHASE_COMPLETE ? 2028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TRACE_EVENT_PHASE_BEGIN : phase, 2029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) category_group_enabled, name, id, 2030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) num_args, arg_names, arg_types, arg_values, 2031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) flags); 2032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 20332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 203458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 203558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (thread_local_event_buffer) 2036a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) thread_local_event_buffer->ReportOverhead(now, thread_now); 20378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 20388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return handle; 20394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 20404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 20411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// May be called when a COMPELETE event ends and the unfinished event has been 20421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// recycled (phase == TRACE_EVENT_PHASE_END and trace_event == NULL). 2043a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string TraceLog::EventToConsoleMessage(unsigned char phase, 2044a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const TimeTicks& timestamp, 2045a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TraceEvent* trace_event) { 2046a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoLock thread_info_lock(thread_info_lock_); 2047a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 20481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The caller should translate TRACE_EVENT_PHASE_COMPLETE to 20491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // TRACE_EVENT_PHASE_BEGIN or TRACE_EVENT_END. 20501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(phase != TRACE_EVENT_PHASE_COMPLETE); 20514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 20524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TimeDelta duration; 20531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int thread_id = trace_event ? 20541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) trace_event->thread_id() : PlatformThread::CurrentId(); 20554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (phase == TRACE_EVENT_PHASE_END) { 20561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) duration = timestamp - thread_event_start_times_[thread_id].top(); 20578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) thread_event_start_times_[thread_id].pop(); 20584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 20594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 20604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string thread_name = thread_names_[thread_id]; 20614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (thread_colors_.find(thread_name) == thread_colors_.end()) 20624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_colors_[thread_name] = (thread_colors_.size() % 6) + 1; 20634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 20644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::ostringstream log; 20654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) log << base::StringPrintf("%s: \x1b[0;3%dm", 20664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_name.c_str(), 20674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_colors_[thread_name]); 20684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 20694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t depth = 0; 20704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (thread_event_start_times_.find(thread_id) != 20714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread_event_start_times_.end()) 20724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) depth = thread_event_start_times_[thread_id].size(); 20734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 20744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < depth; ++i) 20754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) log << "| "; 20764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 20771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (trace_event) 20781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) trace_event->AppendPrettyPrinted(&log); 20794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (phase == TRACE_EVENT_PHASE_END) 20804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) log << base::StringPrintf(" (%.3f ms)", duration.InMillisecondsF()); 20814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2082a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) log << "\x1b[0;m"; 20834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 20841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (phase == TRACE_EVENT_PHASE_BEGIN) 20851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) thread_event_start_times_[thread_id].push(timestamp); 2086a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2087a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return log.str(); 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceLog::AddTraceEventEtw(char phase, 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name, 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* id, 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* extra) { 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEventETWProvider::Trace(name, phase, id, extra); 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceLog::AddTraceEventEtw(char phase, 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* name, 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* id, 2104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& extra) { 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TraceEventETWProvider::Trace(name, phase, id, extra); 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INTERNAL_TRACE_EVENT_ADD(phase, "ETW Trace Event", name, 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_FLAG_COPY, "id", id, "extra", extra); 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void TraceLog::UpdateTraceEventDuration( 2113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const unsigned char* category_group_enabled, 2114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const char* name, 2115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TraceEventHandle handle) { 2116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Avoid re-entrance of AddTraceEvent. This may happen in GPU process when 2117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // ECHO_TO_CONSOLE is enabled: AddTraceEvent -> LOG(ERROR) -> 2118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // GpuProcessLogMessageHandler -> PostPendingTask -> TRACE_EVENT ... 2119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (thread_is_in_trace_event_.Get()) 2120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 2121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoThreadLocalBoolean thread_is_in_trace_event(&thread_is_in_trace_event_); 2123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TimeTicks thread_now = ThreadNow(); 21250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) TimeTicks now = OffsetNow(); 2126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::string console_message; 2128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (*category_group_enabled & ENABLED_FOR_RECORDING) { 2129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) OptionalAutoLock lock(lock_); 2130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TraceEvent* trace_event = GetEventByHandleInternal(handle, &lock); 2132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (trace_event) { 2133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(trace_event->phase() == TRACE_EVENT_PHASE_COMPLETE); 2134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) trace_event->UpdateDuration(now, thread_now); 21358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_ANDROID) 2136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) trace_event->SendToATrace(); 21378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 2138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 21398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 21405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (trace_options() & kInternalEchoToConsole) { 2141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) console_message = EventToConsoleMessage(TRACE_EVENT_PHASE_END, 2142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) now, trace_event); 2143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 21441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 21451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (console_message.size()) 2147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(ERROR) << console_message; 2148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (*category_group_enabled & ENABLED_FOR_EVENT_CALLBACK) { 2150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EventCallback event_callback = reinterpret_cast<EventCallback>( 2151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) subtle::NoBarrier_Load(&event_callback_)); 2152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (event_callback) { 2153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) event_callback(now, TRACE_EVENT_PHASE_END, category_group_enabled, name, 2154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) trace_event_internal::kNoEventId, 0, NULL, NULL, NULL, 2155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TRACE_EVENT_FLAG_NONE); 2156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 21578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 21588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 21598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceLog::SetWatchEvent(const std::string& category_name, 2161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const std::string& event_name, 2162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const WatchEventCallback& callback) { 2163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const unsigned char* category = GetCategoryGroupEnabled( 2164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category_name.c_str()); 21654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AutoLock lock(lock_); 21664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) subtle::NoBarrier_Store(&watch_category_, 21674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) reinterpret_cast<subtle::AtomicWord>(category)); 21684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) watch_event_name_ = event_name; 2169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) watch_event_callback_ = callback; 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceLog::CancelWatchEvent() { 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoLock lock(lock_); 217458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) subtle::NoBarrier_Store(&watch_category_, 0); 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watch_event_name_ = ""; 2176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) watch_event_callback_.Reset(); 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void TraceLog::AddMetadataEventsWhileLocked() { 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lock_.AssertAcquired(); 21817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if !defined(OS_NACL) // NaCl shouldn't expose the process id. 2183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 2184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 0, 2185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "num_cpus", "number", 2186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::SysInfo::NumberOfProcessors()); 2187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif 2188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 21907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int current_thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 21917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (process_sort_index_ != 0) { 2192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 21934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_thread_id, 21944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "process_sort_index", "sort_index", 21954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) process_sort_index_); 21967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 21977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 21987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (process_name_.size()) { 2199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 22004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_thread_id, 22014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "process_name", "name", 22024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) process_name_); 22037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 22047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 22057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (process_labels_.size() > 0) { 22067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::vector<std::string> labels; 22077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for(base::hash_map<int, std::string>::iterator it = process_labels_.begin(); 22087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it != process_labels_.end(); 22097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it++) { 22107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch labels.push_back(it->second); 22117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 22134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_thread_id, 22144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "process_labels", "labels", 22154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JoinString(labels, ',')); 22167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 22177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 22187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Thread sort indices. 22197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for(hash_map<int, int>::iterator it = thread_sort_indices_.begin(); 22207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it != thread_sort_indices_.end(); 22217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it++) { 22227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (it->second == 0) 22237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch continue; 2224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 22254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->first, 22264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "thread_sort_index", "sort_index", 22274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second); 22287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 22297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 22307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Thread names. 2231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AutoLock thread_info_lock(thread_info_lock_); 22322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for(hash_map<int, std::string>::iterator it = thread_names_.begin(); 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != thread_names_.end(); 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it++) { 22357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (it->second.empty()) 22367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch continue; 2237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 22384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->first, 22394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "thread_name", "name", 22404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) it->second); 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 22435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If buffer is full, add a metadata record to report this. 22445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!buffer_limit_reached_timestamp_.is_null()) { 22455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) InitializeMetadataEvent(AddEventToThreadSharedChunkWhileLocked(NULL, false), 22465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) current_thread_id, 22475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "trace_buffer_overflowed", 22485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "overflowed_at_ts", 22495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buffer_limit_reached_timestamp_); 22505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void TraceLog::WaitSamplingEventForTesting() { 22544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!sampling_thread_) 22554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 2256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sampling_thread_->WaitSamplingEventForTesting(); 22572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 22582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceLog::DeleteForTesting() { 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteTraceLogForTesting::Delete(); 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TraceEvent* TraceLog::GetEventByHandle(TraceEventHandle handle) { 22648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return GetEventByHandleInternal(handle, NULL); 22658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 22664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 22678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TraceEvent* TraceLog::GetEventByHandleInternal(TraceEventHandle handle, 22688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OptionalAutoLock* lock) { 22691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!handle.chunk_seq) 22701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 22711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 22724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (thread_local_event_buffer_.Get()) { 22738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TraceEvent* trace_event = 22748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) thread_local_event_buffer_.Get()->GetEventByHandle(handle); 22754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (trace_event) 22764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return trace_event; 22774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 22784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 22798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The event has been out-of-control of the thread local buffer. 22808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Try to get the event from the main buffer with a lock. 22818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (lock) 22828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) lock->EnsureAcquired(); 22834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 22848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (thread_shared_chunk_ && 22858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) handle.chunk_index == thread_shared_chunk_index_) { 22868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return handle.chunk_seq == thread_shared_chunk_->seq() ? 22878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) thread_shared_chunk_->GetEventAt(handle.event_index) : NULL; 22888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 22898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 22908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return logged_events_->GetEventByHandle(handle); 22914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 22924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TraceLog::SetProcessID(int process_id) { 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_id_ = process_id; 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a FNV hash from the process ID for XORing. 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://isthe.com/chongo/tech/comp/fnv/ for algorithm details. 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long offset_basis = 14695981039346656037ull; 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long fnv_prime = 1099511628211ull; 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long long pid = static_cast<unsigned long long>(process_id_); 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_id_hash_ = (offset_basis ^ pid) * fnv_prime; 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TraceLog::SetProcessSortIndex(int sort_index) { 23047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AutoLock lock(lock_); 23057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process_sort_index_ = sort_index; 23067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 23077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 23087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TraceLog::SetProcessName(const std::string& process_name) { 23097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AutoLock lock(lock_); 23107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process_name_ = process_name; 23117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 23127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 23137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TraceLog::UpdateProcessLabel( 23147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int label_id, const std::string& current_label) { 23157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if(!current_label.length()) 23167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return RemoveProcessLabel(label_id); 23177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 23187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AutoLock lock(lock_); 23197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process_labels_[label_id] = current_label; 23207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 23217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 23227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TraceLog::RemoveProcessLabel(int label_id) { 2323ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch AutoLock lock(lock_); 23247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::hash_map<int, std::string>::iterator it = process_labels_.find( 23254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) label_id); 23267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (it == process_labels_.end()) 23277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return; 23287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 23297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch process_labels_.erase(it); 23307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 23317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 23327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TraceLog::SetThreadSortIndex(PlatformThreadId thread_id, int sort_index) { 23337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AutoLock lock(lock_); 23347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch thread_sort_indices_[static_cast<int>(thread_id)] = sort_index; 23357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 23367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 23372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TraceLog::SetTimeOffset(TimeDelta offset) { 23382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) time_offset_ = offset; 23392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 23402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)size_t TraceLog::GetObserverCountForTest() const { 23427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return enabled_state_observer_list_.size(); 23437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 23447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 23458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void TraceLog::SetCurrentThreadBlocksMessageLoop() { 23468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) thread_blocks_message_loop_.Set(true); 23478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (thread_local_event_buffer_.Get()) { 23488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // This will flush the thread local buffer. 23498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) delete thread_local_event_buffer_.Get(); 23508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 23518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 23528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( 2354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& str) { 2355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return str.empty() || 2356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) str.at(0) == ' ' || 2357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) str.at(str.length() - 1) == ' '; 2358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2360b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool CategoryFilter::DoesCategoryGroupContainCategory( 2361b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const char* category_group, 2362b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const char* category) const { 2363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(category); 2364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CStringTokenizer category_group_tokens(category_group, 2365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category_group + strlen(category_group), ","); 2366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (category_group_tokens.GetNext()) { 2367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string category_group_token = category_group_tokens.token(); 2368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Don't allow empty tokens, nor tokens with leading or trailing space. 2369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!CategoryFilter::IsEmptyOrContainsLeadingOrTrailingWhitespace( 2370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category_group_token)) 2371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << "Disallowed category string"; 2372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (MatchPattern(category_group_token.c_str(), category)) 2373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 2374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 2376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CategoryFilter::CategoryFilter(const std::string& filter_string) { 2379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!filter_string.empty()) 2380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Initialize(filter_string); 2381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 2382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Initialize(CategoryFilter::kDefaultCategoryFilterString); 2383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 23855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)CategoryFilter::CategoryFilter() { 23865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Initialize(CategoryFilter::kDefaultCategoryFilterString); 23875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 23885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CategoryFilter::CategoryFilter(const CategoryFilter& cf) 2390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : included_(cf.included_), 2391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) disabled_(cf.disabled_), 23925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) excluded_(cf.excluded_), 23935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delays_(cf.delays_) { 2394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CategoryFilter::~CategoryFilter() { 2397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CategoryFilter& CategoryFilter::operator=(const CategoryFilter& rhs) { 2400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (this == &rhs) 2401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return *this; 2402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) included_ = rhs.included_; 2404b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) disabled_ = rhs.disabled_; 2405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) excluded_ = rhs.excluded_; 24065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delays_ = rhs.delays_; 2407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return *this; 2408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CategoryFilter::Initialize(const std::string& filter_string) { 2411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tokenize list of categories, delimited by ','. 2412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringTokenizer tokens(filter_string, ","); 2413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add each token to the appropriate list (included_,excluded_). 2414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (tokens.GetNext()) { 2415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string category = tokens.token(); 2416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Ignore empty categories. 2417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (category.empty()) 2418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 24195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Synthetic delays are of the form 'DELAY(delay;option;option;...)'. 24205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (category.find(kSyntheticDelayCategoryFilterPrefix) == 0 && 24215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) category.at(category.size() - 1) == ')') { 24225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) category = category.substr( 24235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) strlen(kSyntheticDelayCategoryFilterPrefix), 24245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) category.size() - strlen(kSyntheticDelayCategoryFilterPrefix) - 1); 24255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t name_length = category.find(';'); 24265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (name_length != std::string::npos && name_length > 0 && 24275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) name_length != category.size() - 1) { 24285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delays_.push_back(category); 24295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 24305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (category.at(0) == '-') { 24315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Excluded categories start with '-'. 2432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Remove '-' from category string. 2433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) category = category.substr(1); 2434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) excluded_.push_back(category); 2435b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } else if (category.compare(0, strlen(TRACE_DISABLED_BY_DEFAULT("")), 2436b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) TRACE_DISABLED_BY_DEFAULT("")) == 0) { 2437b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) disabled_.push_back(category); 2438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 2439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) included_.push_back(category); 2440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2444b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void CategoryFilter::WriteString(const StringList& values, 2445b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) std::string* out, 2446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool included) const { 2447b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) bool prepend_comma = !out->empty(); 2448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int token_cnt = 0; 2449b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (StringList::const_iterator ci = values.begin(); 2450b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ci != values.end(); ++ci) { 2451b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (token_cnt > 0 || prepend_comma) 2452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringAppendF(out, ","); 2453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StringAppendF(out, "%s%s", (included ? "" : "-"), ci->c_str()); 2454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++token_cnt; 2455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 24585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CategoryFilter::WriteString(const StringList& delays, 24595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string* out) const { 24605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool prepend_comma = !out->empty(); 24615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int token_cnt = 0; 24625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (StringList::const_iterator ci = delays.begin(); 24635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ci != delays.end(); ++ci) { 24645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (token_cnt > 0 || prepend_comma) 24655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringAppendF(out, ","); 24665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StringAppendF(out, "%s%s)", kSyntheticDelayCategoryFilterPrefix, 24675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ci->c_str()); 24685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++token_cnt; 24695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 24705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 24715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string CategoryFilter::ToString() const { 2473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string filter_string; 2474b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) WriteString(included_, &filter_string, true); 2475b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) WriteString(disabled_, &filter_string, true); 2476b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) WriteString(excluded_, &filter_string, false); 24775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) WriteString(delays_, &filter_string); 2478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return filter_string; 2479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CategoryFilter::IsCategoryGroupEnabled( 2482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* category_group_name) const { 2483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TraceLog should call this method only as part of enabling/disabling 2484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // categories. 2485b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) StringList::const_iterator ci; 2486b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2487b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Check the disabled- filters and the disabled-* wildcard first so that a 2488b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // "*" filter does not include the disabled. 2489b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (ci = disabled_.begin(); ci != disabled_.end(); ++ci) { 2490b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str())) 2491b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return true; 2492b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 2493b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (DoesCategoryGroupContainCategory(category_group_name, 2494b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) TRACE_DISABLED_BY_DEFAULT("*"))) 2495b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 2496b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2497b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (ci = included_.begin(); ci != included_.end(); ++ci) { 2498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str())) 2499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 2500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2501b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2502b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (ci = excluded_.begin(); ci != excluded_.end(); ++ci) { 2503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (DoesCategoryGroupContainCategory(category_group_name, ci->c_str())) 2504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 2505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the category group is not excluded, and there are no included patterns 2507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // we consider this pattern enabled. 2508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return included_.empty(); 2509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2511b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)bool CategoryFilter::HasIncludedPatterns() const { 2512b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return !included_.empty(); 2513b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 2514b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CategoryFilter::Merge(const CategoryFilter& nested_filter) { 2516b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Keep included patterns only if both filters have an included entry. 2517b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Otherwise, one of the filter was specifying "*" and we want to honour the 2518b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // broadest filter. 2519b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (HasIncludedPatterns() && nested_filter.HasIncludedPatterns()) { 2520b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) included_.insert(included_.end(), 2521b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) nested_filter.included_.begin(), 2522b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) nested_filter.included_.end()); 2523b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } else { 2524b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) included_.clear(); 2525b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 2526b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 2527b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) disabled_.insert(disabled_.end(), 2528b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) nested_filter.disabled_.begin(), 2529b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) nested_filter.disabled_.end()); 2530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) excluded_.insert(excluded_.end(), 2531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) nested_filter.excluded_.begin(), 2532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) nested_filter.excluded_.end()); 25335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delays_.insert(delays_.end(), 25345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) nested_filter.delays_.begin(), 25355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) nested_filter.delays_.end()); 2536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CategoryFilter::Clear() { 2539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) included_.clear(); 2540b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) disabled_.clear(); 2541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) excluded_.clear(); 2542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const CategoryFilter::StringList& 25455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CategoryFilter::GetSyntheticDelayValues() const { 25465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return delays_; 25475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 25485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace debug 25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 25512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace trace_event_internal { 25532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ScopedTraceBinaryEfficient::ScopedTraceBinaryEfficient( 25558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) const char* category_group, const char* name) { 25568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // The single atom works because for now the category_group can only be "gpu". 25578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(strcmp(category_group, "gpu") == 0); 25588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static TRACE_EVENT_API_ATOMIC_WORD atomic = 0; 25598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( 25608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) category_group, atomic, category_group_enabled_); 2561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) name_ = name; 2562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (*category_group_enabled_) { 25638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) event_handle_ = 25648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( 25658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) TRACE_EVENT_PHASE_COMPLETE, category_group_enabled_, name, 25668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) trace_event_internal::kNoEventId, 25678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) static_cast<int>(base::PlatformThread::CurrentId()), 25688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::TimeTicks::NowFromSystemTraceTime(), 25698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 0, NULL, NULL, NULL, NULL, TRACE_EVENT_FLAG_NONE); 25702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 25712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 25722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ScopedTraceBinaryEfficient::~ScopedTraceBinaryEfficient() { 2574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (*category_group_enabled_) { 2575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(category_group_enabled_, 2576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) name_, event_handle_); 2577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 25782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 25792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace trace_event_internal 2581