13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/tracked_objects.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <math.h> 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/format_macros.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h" 133f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::TimeDelta; 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace tracked_objects { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A TLS slot to the TrackRegistry for the current thread. 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenbase::ThreadLocalStorage::Slot ThreadData::tls_index_(base::LINKER_INITIALIZED); 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// A global state variable to prevent repeated initialization during tests. 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottAutoTracking::State AutoTracking::state_ = AutoTracking::kNeverBeenRun; 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Death data tallies durations when a death takes place. 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DeathData::RecordDeath(const TimeDelta& duration) { 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++count_; 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott life_duration_ += duration; 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 milliseconds = duration.InMilliseconds(); 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott square_duration_ += milliseconds * milliseconds; 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint DeathData::AverageMsDuration() const { 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return static_cast<int>(life_duration_.InMilliseconds() / count_); 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottdouble DeathData::StandardDeviation() const { 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott double average = AverageMsDuration(); 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott double variance = static_cast<float>(square_duration_)/count_ 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott - average * average; 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return sqrt(variance); 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DeathData::AddDeathData(const DeathData& other) { 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott count_ += other.count_; 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott life_duration_ += other.life_duration_; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott square_duration_ += other.square_duration_; 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DeathData::Write(std::string* output) const { 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!count_) 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (1 == count_) { 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "(1)Life in %dms ", AverageMsDuration()); 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "(%d)Lives %dms/life ", 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick count_, AverageMsDuration()); 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DeathData::Clear() { 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott count_ = 0; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott life_duration_ = TimeDelta(); 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott square_duration_ = 0; 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBirthOnThread::BirthOnThread(const Location& location) 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : location_(location), 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_thread_(ThreadData::current()) { } 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBirths::Births(const Location& location) 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : BirthOnThread(location), 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_count_(1) { } 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ThreadData maintains the central data for all births and death. 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottThreadData* ThreadData::first_ = NULL; 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbase::Lock ThreadData::list_lock_; 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED; 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochThreadData::ThreadData() : next_(NULL) { 94201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // This shouldn't use the MessageLoop::current() LazyInstance since this might 95201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // be used on a non-joinable thread. 96201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // http://crbug.com/62728 97201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; 98201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch message_loop_ = MessageLoop::current(); 99201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickThreadData::~ThreadData() {} 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottThreadData* ThreadData::current() { 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!tls_index_.initialized()) 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return NULL; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData* registry = static_cast<ThreadData*>(tls_index_.Get()); 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!registry) { 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We have to create a new registry for ThreadData. 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool too_late_to_create = false; 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott registry = new ThreadData; 11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(list_lock_); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Use lock to insure we have most recent status. 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!IsActive()) { 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott too_late_to_create = true; 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Use lock to insert into list. 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott registry->next_ = first_; 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott first_ = registry; 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } // Release lock. 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (too_late_to_create) { 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete registry; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott registry = NULL; 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tls_index_.Set(registry); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return registry; 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Do mininimal fixups for searching function names. 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic std::string UnescapeQuery(const std::string& query) { 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string result; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < query.size(); i++) { 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char next = query[i]; 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if ('%' == next && i + 2 < query.size()) { 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string hex = query.substr(i + 1, 2); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char replacement = '\0'; 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Only bother with "<", ">", and " ". 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (LowerCaseEqualsASCII(hex, "3c")) 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott replacement ='<'; 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else if (LowerCaseEqualsASCII(hex, "3e")) 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott replacement = '>'; 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else if (hex == "20") 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott replacement = ' '; 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (replacement) { 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next = replacement; 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott i += 2; 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott result.push_back(next); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result; 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::WriteHTML(const std::string& query, std::string* output) { 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ThreadData::IsActive()) 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; // Not yet initialized. 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(ThreadData::current()); 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch output->append("<html><head><title>About Tasks"); 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string escaped_query = UnescapeQuery(query); 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!escaped_query.empty()) 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append(" - " + escaped_query); 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("</title></head><body><pre>"); 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DataCollector collected_data; // Gather data. 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott collected_data.AddListOfLivingObjects(); // Add births that are still alive. 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Data Gathering is complete. Now to sort/process/render. 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DataCollector::Collection* collection = collected_data.collection(); 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Create filtering and sort comparison object. 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Comparator comparator; 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott comparator.ParseQuery(escaped_query); 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Filter out acceptable (matching) instances. 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DataCollector::Collection match_array; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (DataCollector::Collection::iterator it = collection->begin(); 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != collection->end(); ++it) { 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (comparator.Acceptable(*it)) 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott match_array.push_back(*it); 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott comparator.Sort(&match_array); 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WriteHTMLTotalAndSubtotals(match_array, comparator, output); 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott comparator.Clear(); // Delete tiebreaker_ instances. 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("</pre>"); 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* help_string = "The following are the keywords that can be used to" 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "sort and aggregate the data, or to select data.<br><ul>" 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>count</b> Number of instances seen." 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>duration</b> Duration in ms from construction to descrution." 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>birth</b> Thread on which the task was constructed." 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>death</b> Thread on which the task was run and deleted." 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>file</b> File in which the task was contructed." 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>function</b> Function in which the task was constructed." 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>line</b> Line number of the file in which the task was constructed." 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "</ul><br>" 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "As examples:<ul>" 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>about:tasks/file</b> would sort the above data by file, and" 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " aggregate data on a per-file basis." 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>about:tasks/file=Dns</b> would only list data for tasks constructed" 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " in a file containing the text |Dns|." 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "<li><b>about:tasks/birth/death</b> would sort the above list by birth" 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " thread, and then by death thread, and would aggregate data for each pair" 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " of lifetime events." 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "</ul>" 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " The data can be reset to zero (discarding all births, deaths, etc.) using" 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " <b>about:tasks/reset</b>. The existing stats will be displayed, but the" 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " internal stats will be set to zero, and start accumulating afresh. This" 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " option is very helpful if you only wish to consider tasks created after" 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " some point in time.<br><br>" 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott "If you wish to monitor Renderer events, be sure to run in --single-process" 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott " mode."; 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append(help_string); 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("</body></html>"); 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::WriteHTMLTotalAndSubtotals( 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const DataCollector::Collection& match_array, 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const Comparator& comparator, 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* output) { 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!match_array.size()) { 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("There were no tracked matches."); 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Aggregate during printing 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Aggregation totals; 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < match_array.size(); ++i) { 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott totals.AddDeathSnapshot(match_array[i]); 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("Aggregate Stats: "); 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott totals.Write(output); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("<hr><hr>"); 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Aggregation subtotals; 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < match_array.size(); ++i) { 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (0 == i || !comparator.Equivalent(match_array[i - 1], 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott match_array[i])) { 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Print group's defining characteristics. 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott comparator.WriteSortGrouping(match_array[i], output); 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("<br><br>"); 252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott comparator.WriteSnapshot(match_array[i], output); 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("<br>"); 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott subtotals.AddDeathSnapshot(match_array[i]); 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (i + 1 >= match_array.size() || 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !comparator.Equivalent(match_array[i], 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott match_array[i + 1])) { 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Print aggregate stats for the group. 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("<br>"); 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott subtotals.Write(output); 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("<br><hr><br>"); 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott subtotals.Clear(); 264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBirths* ThreadData::TallyABirth(const Location& location) { 270201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { 271201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // This shouldn't use the MessageLoop::current() LazyInstance since this 272201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // might be used on a non-joinable thread. 273201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // http://crbug.com/62728 274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; 275201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!message_loop_) // In case message loop wasn't yet around... 276201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch message_loop_ = MessageLoop::current(); // Find it now. 277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BirthMap::iterator it = birth_map_.find(location); 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (it != birth_map_.end()) { 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it->second->RecordBirth(); 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return it->second; 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Births* tracker = new Births(location); 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Lock since the map may get relocated now, and other threads sometimes 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // snapshot it (but they lock before copying it). 28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_map_[location] = tracker; 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return tracker; 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::TallyADeath(const Births& lifetimes, 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const TimeDelta& duration) { 295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch { 296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // http://crbug.com/62728 297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; 298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!message_loop_) // In case message loop wasn't yet around... 299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch message_loop_ = MessageLoop::current(); // Find it now. 300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DeathMap::iterator it = death_map_.find(&lifetimes); 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (it != death_map_.end()) { 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it->second.RecordDeath(duration); 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); // Lock since the map may get relocated now. 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_map_[&lifetimes].RecordDeath(duration); 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottThreadData* ThreadData::first() { 31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(list_lock_); 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return first_; 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst std::string ThreadData::ThreadName() const { 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (message_loop_) 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return message_loop_->thread_name(); 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "ThreadWithoutMessageLoop"; 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This may be called from another thread. 325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::SnapshotBirthMap(BirthMap *output) const { 32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (BirthMap::const_iterator it = birth_map_.begin(); 328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != birth_map_.end(); ++it) 329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (*output)[it->first] = it->second; 330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This may be called from another thread. 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::SnapshotDeathMap(DeathMap *output) const { 33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (DeathMap::const_iterator it = death_map_.begin(); 336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != death_map_.end(); ++it) 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott (*output)[it->first] = it->second; 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::ResetAllThreadData() { 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData* my_list = ThreadData::current()->first(); 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (ThreadData* thread_data = my_list; 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data; 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data = thread_data->next()) 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data->Reset(); 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::Reset() { 35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (DeathMap::iterator it = death_map_.begin(); 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != death_map_.end(); ++it) 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it->second.Clear(); 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (BirthMap::iterator it = birth_map_.begin(); 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != birth_map_.end(); ++it) 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it->second->Clear(); 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef OS_WIN 3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// A class used to count down which is accessed by several threads. This is 3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// used to make sure RunOnAllThreads() actually runs a task on the expected 3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// count of threads. 3643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ThreadData::ThreadSafeDownCounter { 3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Constructor sets the count, once and for all. 3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick explicit ThreadSafeDownCounter(size_t count); 3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Decrement the count, and return true if we hit zero. Also delete this 3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // instance automatically when we hit zero. 3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick bool LastCaller(); 3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick size_t remaining_count_; 37572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::Lock lock_; // protect access to remaining_count_. 3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickThreadData::ThreadSafeDownCounter::ThreadSafeDownCounter(size_t count) 3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : remaining_count_(count) { 3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK_GT(remaining_count_, 0u); 3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ThreadData::ThreadSafeDownCounter::LastCaller() { 3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick { 38572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(lock_); 3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (--remaining_count_) 3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } // Release lock, so we can delete everything in this instance. 3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick delete this; 3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// A Task class that runs a static method supplied, and checks to see if this 3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// is the last tasks instance (on last thread) that will run the method. 3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// IF this is the last run, then the supplied event is signalled. 3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass ThreadData::RunTheStatic : public Task { 3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public: 3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick typedef void (*FunctionPointer)(); 3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick RunTheStatic(FunctionPointer function, 4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HANDLE completion_handle, 4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ThreadSafeDownCounter* counter); 4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Run the supplied static method, and optionally set the event. 4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick void Run(); 4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private: 4063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FunctionPointer function_; 4073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HANDLE completion_handle_; 4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Make sure enough tasks are called before completion is signaled. 4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ThreadSafeDownCounter* counter_; 4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DISALLOW_COPY_AND_ASSIGN(RunTheStatic); 4123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}; 4133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4143345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickThreadData::RunTheStatic::RunTheStatic(FunctionPointer function, 4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick HANDLE completion_handle, 4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ThreadSafeDownCounter* counter) 4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : function_(function), 4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick completion_handle_(completion_handle), 4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick counter_(counter) { 4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ThreadData::RunTheStatic::Run() { 4233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick function_(); 4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (counter_->LastCaller()) 4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SetEvent(completion_handle_); 4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TODO(jar): This should use condition variables, and be cross platform. 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::RunOnAllThreads(void (*function)()) { 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData* list = first(); // Get existing list. 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::vector<MessageLoop*> message_loops; 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (ThreadData* it = list; it; it = it->next()) { 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (current() != it && it->message_loop()) 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott message_loops.push_back(it->message_loop()); 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadSafeDownCounter* counter = 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new ThreadSafeDownCounter(message_loops.size() + 1); // Extra one for us! 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE completion_handle = CreateEvent(NULL, false, false, NULL); 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Tell all other threads to run. 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < message_loops.size(); ++i) 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch message_loops[i]->PostTask( 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FROM_HERE, new RunTheStatic(function, completion_handle, counter)); 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Also run Task on our thread. 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RunTheStatic local_task(function, completion_handle, counter); 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott local_task.Run(); 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WaitForSingleObject(completion_handle, INFINITE); 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int ret_val = CloseHandle(completion_handle); 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(ret_val); 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif // OS_WIN 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ThreadData::StartTracking(bool status) { 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef TRACK_ALL_TASK_OBJECTS 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; // Not compiled in. 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!status) { 46472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(list_lock_); 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(status_ == ACTIVE || status_ == SHUTDOWN); 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott status_ = SHUTDOWN; 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 46972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(list_lock_); 470dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen DCHECK_EQ(UNINITIALIZED, status_); 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CHECK(tls_index_.Initialize(NULL)); 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott status_ = ACTIVE; 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool ThreadData::IsActive() { 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return status_ == ACTIVE; 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef OS_WIN 482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::ShutdownMultiThreadTracking() { 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Using lock, guarantee that no new ThreadData instances will be created. 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!StartTracking(false)) 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RunOnAllThreads(ShutdownDisablingFurtherTracking); 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Now the *only* threads that might change the database are the threads with 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // no messages loops. They might still be adding data to their birth records, 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // but since no objects are deleted on those threads, there will be no further 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // access to to cross-thread data. 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We could do a cleanup on all threads except for the ones without 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // MessageLoops, but we won't bother doing cleanup (destruction of data) yet. 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::ShutdownSingleThreadedCleanup() { 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We must be single threaded... but be careful anyway. 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!StartTracking(false)) 504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData* thread_data_list; 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 50772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(list_lock_); 508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data_list = first_; 509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott first_ = NULL; 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott while (thread_data_list) { 513c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData* next_thread_data = thread_data_list; 514c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data_list = thread_data_list->next(); 515c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 516c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (BirthMap::iterator it = next_thread_data->birth_map_.begin(); 517c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_thread_data->birth_map_.end() != it; ++it) 518c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete it->second; // Delete the Birth Records. 519c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_thread_data->birth_map_.clear(); 520c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott next_thread_data->death_map_.clear(); 521c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete next_thread_data; // Includes all Death Records. 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CHECK(tls_index_.initialized()); 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tls_index_.Free(); 526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!tls_index_.initialized()); 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott status_ = UNINITIALIZED; 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 530c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static 531c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid ThreadData::ShutdownDisablingFurtherTracking() { 532c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Redundantly set status SHUTDOWN on this thread. 533c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!StartTracking(false)) 534c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 535c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 536c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 537c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 538c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Individual 3-tuple of birth (place and thread) along with death thread, and 539c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// the accumulated stats for instances (DeathData). 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSnapshot::Snapshot(const BirthOnThread& birth_on_thread, 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const ThreadData& death_thread, 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const DeathData& death_data) 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : birth_(&birth_on_thread), 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_thread_(&death_thread), 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_data_(death_data) { 547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSnapshot::Snapshot(const BirthOnThread& birth_on_thread, int count) 550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : birth_(&birth_on_thread), 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_thread_(NULL), 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_data_(DeathData(count)) { 553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst std::string Snapshot::DeathThreadName() const { 556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (death_thread_) 557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return death_thread_->ThreadName(); 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return "Still_Alive"; 559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Snapshot::Write(std::string* output) const { 562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_data_.Write(output); 5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "%s->%s ", 5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick birth_->birth_thread()->ThreadName().c_str(), 5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick death_thread_->ThreadName().c_str()); 566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_->location().Write(true, true, output); 567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Snapshot::Add(const Snapshot& other) { 570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_data_.AddDeathData(other.death_data_); 571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// DataCollector 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottDataCollector::DataCollector() { 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(ThreadData::IsActive()); 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get an unchanging copy of a ThreadData list. 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData* my_list = ThreadData::current()->first(); 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 582c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott count_of_contributing_threads_ = 0; 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (ThreadData* thread_data = my_list; 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data; 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data = thread_data->next()) { 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ++count_of_contributing_threads_; 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 588c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Gather data serially. A different constructor could be used to do in 590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // parallel, and then invoke an OnCompletion task. 591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This hackish approach *can* get some slighly corrupt tallies, as we are 592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // grabbing values without the protection of a lock, but it has the advantage 593c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // of working even with threads that don't have message loops. If a user 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // sees any strangeness, they can always just run their stats gathering a 595c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // second time. 596c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // TODO(jar): Provide version that gathers stats safely via PostTask in all 597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // cases where thread_data supplies a message_loop to post to. Be careful to 598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // handle message_loops that are destroyed!?! 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (ThreadData* thread_data = my_list; 600c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data; 601c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data = thread_data->next()) { 602c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Append(*thread_data); 603c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 604c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 605c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6063345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDataCollector::~DataCollector() { 6073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 609c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DataCollector::Append(const ThreadData& thread_data) { 610c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get copy of data (which is done under ThreadData's lock). 611c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData::BirthMap birth_map; 612c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data.SnapshotBirthMap(&birth_map); 613c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData::DeathMap death_map; 614c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott thread_data.SnapshotDeathMap(&death_map); 615c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 616c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Use our lock to protect our accumulation activity. 61772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(accumulation_lock_); 618c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 619c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(count_of_contributing_threads_); 620c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (ThreadData::DeathMap::const_iterator it = death_map.begin(); 622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != death_map.end(); ++it) { 623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott collection_.push_back(Snapshot(*it->first, thread_data, it->second)); 624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott global_birth_count_[it->first] -= it->first->birth_count(); 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (ThreadData::BirthMap::const_iterator it = birth_map.begin(); 628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != birth_map.end(); ++it) { 629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott global_birth_count_[it->second] += it->second->birth_count(); 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott --count_of_contributing_threads_; 633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottDataCollector::Collection* DataCollector::collection() { 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!count_of_contributing_threads_); 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return &collection_; 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid DataCollector::AddListOfLivingObjects() { 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!count_of_contributing_threads_); 642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (BirthCount::iterator it = global_birth_count_.begin(); 643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott it != global_birth_count_.end(); ++it) { 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (it->second > 0) 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott collection_.push_back(Snapshot(*it->first, it->second)); 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Aggregation 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6523345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAggregation::Aggregation() 6533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : birth_count_(0) { 6543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6563345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickAggregation::~Aggregation() { 6573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Aggregation::AddDeathSnapshot(const Snapshot& snapshot) { 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddBirth(snapshot.birth()); 661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_threads_[snapshot.death_thread()]++; 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddDeathData(snapshot.death_data()); 663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Aggregation::AddBirths(const Births& births) { 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddBirth(births); 667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_count_ += births.birth_count(); 668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Aggregation::AddBirth(const BirthOnThread& birth) { 670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott AddBirthPlace(birth.location()); 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_threads_[birth.birth_thread()]++; 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Aggregation::AddBirthPlace(const Location& location) { 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott locations_[location]++; 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_files_[location.file_name()]++; 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Aggregation::Write(std::string* output) const { 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (locations_.size() == 1) { 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott locations_.begin()->first.Write(true, true, output); 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 6833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "%" PRIuS " Locations. ", locations_.size()); 6843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (birth_files_.size() > 1) { 6853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "%" PRIuS " Files. ", birth_files_.size()); 6863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 6873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "All born in %s. ", 6883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick birth_files_.begin()->first.c_str()); 6893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 6923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (birth_threads_.size() > 1) { 6933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "%" PRIuS " BirthingThreads. ", 6943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick birth_threads_.size()); 6953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 6963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "All born on %s. ", 6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick birth_threads_.begin()->first->ThreadName().c_str()); 6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (death_threads_.size() > 1) { 7013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "%" PRIuS " DeathThreads. ", 7023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick death_threads_.size()); 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 7043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (death_threads_.begin()->first) { 7053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "All deleted on %s. ", 7063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick death_threads_.begin()->first->ThreadName().c_str()); 7073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("All these objects are still alive."); 7093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (birth_count_ > 1) 7133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "Births=%d ", birth_count_); 714c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 715c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DeathData::Write(output); 716c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 717c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 718c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Aggregation::Clear() { 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_count_ = 0; 720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_files_.clear(); 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott locations_.clear(); 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott birth_threads_.clear(); 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DeathData::Clear(); 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott death_threads_.clear(); 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//------------------------------------------------------------------------------ 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Comparison object for sorting. 729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottComparator::Comparator() 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott : selector_(NIL), 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_(NULL), 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott combined_selectors_(0), 734c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott use_tiebreaker_for_sort_only_(false) {} 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 736c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Comparator::Clear() { 737c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (tiebreaker_) { 738c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_->Clear(); 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete tiebreaker_; 740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_ = NULL; 741c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 742c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott use_tiebreaker_for_sort_only_ = false; 743c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott selector_ = NIL; 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 745c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 746c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Comparator::operator()(const Snapshot& left, 747c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const Snapshot& right) const { 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (selector_) { 749c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_THREAD: 750c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.birth_thread() != right.birth_thread() && 751c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott left.birth_thread()->ThreadName() != 752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.birth_thread()->ThreadName()) 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return left.birth_thread()->ThreadName() < 754c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.birth_thread()->ThreadName(); 755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 756c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 757c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DEATH_THREAD: 758c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.death_thread() != right.death_thread() && 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott left.DeathThreadName() != 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.DeathThreadName()) { 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!left.death_thread()) 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!right.death_thread()) 764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return left.DeathThreadName() < 766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.DeathThreadName(); 767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_FILE: 771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.location().file_name() != right.location().file_name()) { 772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int comp = strcmp(left.location().file_name(), 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.location().file_name()); 774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (comp) 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0 > comp; 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_FUNCTION: 780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.location().function_name() != right.location().function_name()) { 781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int comp = strcmp(left.location().function_name(), 782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.location().function_name()); 783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (comp) 784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0 > comp; 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_LINE: 789c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.location().line_number() != right.location().line_number()) 790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return left.location().line_number() < 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.location().line_number(); 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case COUNT: 795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.count() != right.count()) 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return left.count() > right.count(); // Sort large at front of vector. 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case AVERAGE_DURATION: 800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!left.count() || !right.count()) 801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.AverageMsDuration() != right.AverageMsDuration()) 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return left.AverageMsDuration() > right.AverageMsDuration(); 804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (tiebreaker_) 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return tiebreaker_->operator()(left, right); 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 81472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid Comparator::Sort(DataCollector::Collection* collection) const { 81572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::sort(collection->begin(), collection->end(), *this); 81672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 81772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Comparator::Equivalent(const Snapshot& left, 819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const Snapshot& right) const { 820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (selector_) { 821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_THREAD: 822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.birth_thread() != right.birth_thread() && 823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott left.birth_thread()->ThreadName() != 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.birth_thread()->ThreadName()) 825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DEATH_THREAD: 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.death_thread() != right.death_thread() && 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott left.DeathThreadName() != right.DeathThreadName()) 831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_FILE: 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.location().file_name() != right.location().file_name()) { 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int comp = strcmp(left.location().file_name(), 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.location().file_name()); 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (comp) 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_FUNCTION: 844c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.location().function_name() != right.location().function_name()) { 845c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int comp = strcmp(left.location().function_name(), 846c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott right.location().function_name()); 847c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (comp) 848c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 849c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 850c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case COUNT: 853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.count() != right.count()) 854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case AVERAGE_DURATION: 858c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (left.life_duration() != right.life_duration()) 859c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 860c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 861c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 862c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 863c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 864c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 865c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (tiebreaker_ && !use_tiebreaker_for_sort_only_) 866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return tiebreaker_->Equivalent(left, right); 867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Comparator::Acceptable(const Snapshot& sample) const { 871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (required_.size()) { 872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (selector_) { 873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_THREAD: 874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sample.birth_thread()->ThreadName().find(required_) == 875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string::npos) 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DEATH_THREAD: 880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (sample.DeathThreadName().find(required_) == std::string::npos) 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_FILE: 885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!strstr(sample.location().file_name(), required_.c_str())) 886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 889c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_FUNCTION: 890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!strstr(sample.location().function_name(), required_.c_str())) 891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (tiebreaker_ && !use_tiebreaker_for_sort_only_) 899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return tiebreaker_->Acceptable(sample); 900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Comparator::SetTiebreaker(Selector selector, const std::string& required) { 904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (selector == selector_ || NIL == selector) 905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott combined_selectors_ |= selector; 907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (NIL == selector_) { 908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott selector_ = selector; 909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (required.size()) 910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott required_ = required; 911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (tiebreaker_) { 914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (use_tiebreaker_for_sort_only_) { 915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Comparator* temp = new Comparator; 916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott temp->tiebreaker_ = tiebreaker_; 917c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_ = temp; 918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_ = new Comparator; 921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(!use_tiebreaker_for_sort_only_); 922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_->SetTiebreaker(selector, required); 924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Comparator::IsGroupedBy(Selector selector) const { 927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0 != (selector & combined_selectors_); 928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Comparator::SetSubgroupTiebreaker(Selector selector) { 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (selector == selector_ || NIL == selector) 932c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 933c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!tiebreaker_) { 934c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott use_tiebreaker_for_sort_only_ = true; 935c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_ = new Comparator; 936c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_->SetTiebreaker(selector, ""); 937c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 938c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott tiebreaker_->SetSubgroupTiebreaker(selector); 939c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 940c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 941c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 942c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Comparator::ParseKeyphrase(const std::string& key_phrase) { 943c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott typedef std::map<const std::string, Selector> KeyMap; 944c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static KeyMap key_map; 945c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool initialized = false; 946c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!initialized) { 947c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott initialized = true; 948c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Sorting and aggretation keywords, which specify how to sort the data, or 949c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // can specify a required match from the specified field in the record. 950c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_map["count"] = COUNT; 951c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_map["duration"] = AVERAGE_DURATION; 952c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_map["birth"] = BIRTH_THREAD; 953c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_map["death"] = DEATH_THREAD; 954c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_map["file"] = BIRTH_FILE; 955c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_map["function"] = BIRTH_FUNCTION; 956c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_map["line"] = BIRTH_LINE; 957c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 958c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Immediate commands that do not involve setting sort order. 959c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key_map["reset"] = RESET_ALL_DATA; 960c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 961c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 962c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string required; 963c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Watch for: "sort_key=value" as we parse. 964c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t equal_offset = key_phrase.find('=', 0); 965c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (key_phrase.npos != equal_offset) { 966c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // There is a value that must be matched for the data to display. 967c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott required = key_phrase.substr(equal_offset + 1, key_phrase.npos); 968c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 969c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string keyword(key_phrase.substr(0, equal_offset)); 970c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott keyword = StringToLowerASCII(keyword); 971c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott KeyMap::iterator it = key_map.find(keyword); 972c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (key_map.end() == it) 973c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; // Unknown keyword. 974c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (it->second == RESET_ALL_DATA) 975c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ThreadData::ResetAllThreadData(); 976c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott else 977c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetTiebreaker(key_map[keyword], required); 978c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 979c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 980c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Comparator::ParseQuery(const std::string& query) { 981c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Parse each keyphrase between consecutive slashes. 982c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (size_t i = 0; i < query.size();) { 983c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott size_t slash_offset = query.find('/', i); 984c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ParseKeyphrase(query.substr(i, slash_offset - i)); 985c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (query.npos == slash_offset) 986c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 987c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott i = slash_offset + 1; 988c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 989c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 990c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Select subgroup ordering (if we want to display the subgroup) 991c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetSubgroupTiebreaker(COUNT); 992c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetSubgroupTiebreaker(AVERAGE_DURATION); 993c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetSubgroupTiebreaker(BIRTH_THREAD); 994c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetSubgroupTiebreaker(DEATH_THREAD); 995c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetSubgroupTiebreaker(BIRTH_FUNCTION); 996c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetSubgroupTiebreaker(BIRTH_FILE); 997c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SetSubgroupTiebreaker(BIRTH_LINE); 998c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 999c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 1000c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1001c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1002c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool Comparator::WriteSortGrouping(const Snapshot& sample, 1003c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* output) const { 1004c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool wrote_data = false; 1005c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (selector_) { 1006c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_THREAD: 10073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "All new on %s ", 10083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sample.birth_thread()->ThreadName().c_str()); 1009c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wrote_data = true; 1010c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1011c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1012c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case DEATH_THREAD: 10133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (sample.death_thread()) { 10143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "All deleted on %s ", 10153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sample.DeathThreadName().c_str()); 10163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 1017c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("All still alive "); 10183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1019c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wrote_data = true; 1020c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1021c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1022c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_FILE: 10233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "All born in %s ", 10243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sample.location().file_name()); 1025c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1026c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1027c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case BIRTH_FUNCTION: 1028c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->append("All born in "); 1029c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sample.location().WriteFunctionName(output); 1030c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output->push_back(' '); 1031c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1032c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1033c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 1034c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 1035c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1036c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (tiebreaker_ && !use_tiebreaker_for_sort_only_) { 1037c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott wrote_data |= tiebreaker_->WriteSortGrouping(sample, output); 1038c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 1039c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return wrote_data; 1040c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1041c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1042c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid Comparator::WriteSnapshot(const Snapshot& sample, 1043c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string* output) const { 1044c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sample.death_data().Write(output); 1045c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!(combined_selectors_ & BIRTH_THREAD) || 1046c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !(combined_selectors_ & DEATH_THREAD)) 10473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base::StringAppendF(output, "%s->%s ", 10483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (combined_selectors_ & BIRTH_THREAD) ? "*" : 10493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sample.birth().birth_thread()->ThreadName().c_str(), 10503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (combined_selectors_ & DEATH_THREAD) ? "*" : 10513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sample.DeathThreadName().c_str()); 1052c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), 1053c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott !(combined_selectors_ & BIRTH_FUNCTION), 1054c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output); 1055c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 1056c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1057c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace tracked_objects 1058