| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/tracked_objects.h" | 5 #include "base/tracked_objects.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 | 8 |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/thread_restrictions.h" |
| 13 | 14 |
| 14 using base::TimeDelta; | 15 using base::TimeDelta; |
| 15 | 16 |
| 16 namespace tracked_objects { | 17 namespace tracked_objects { |
| 17 | 18 |
| 18 // A TLS slot to the TrackRegistry for the current thread. | 19 // A TLS slot to the TrackRegistry for the current thread. |
| 19 // static | 20 // static |
| 20 TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED); | 21 TLSSlot ThreadData::tls_index_(base::LINKER_INITIALIZED); |
| 21 | 22 |
| 22 // A global state variable to prevent repeated initialization during tests. | 23 // A global state variable to prevent repeated initialization during tests. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 // ThreadData maintains the central data for all births and death. | 83 // ThreadData maintains the central data for all births and death. |
| 83 | 84 |
| 84 // static | 85 // static |
| 85 ThreadData* ThreadData::first_ = NULL; | 86 ThreadData* ThreadData::first_ = NULL; |
| 86 // static | 87 // static |
| 87 Lock ThreadData::list_lock_; | 88 Lock ThreadData::list_lock_; |
| 88 | 89 |
| 89 // static | 90 // static |
| 90 ThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED; | 91 ThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED; |
| 91 | 92 |
| 92 ThreadData::ThreadData() : next_(NULL), message_loop_(MessageLoop::current()) {} | 93 ThreadData::ThreadData() : next_(NULL) { |
| 94 // This shouldn't use the MessageLoop::current() LazyInstance since this might |
| 95 // be used on a non-joinable thread. |
| 96 // http://crbug.com/62728 |
| 97 base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; |
| 98 message_loop_ = MessageLoop::current(); |
| 99 } |
| 93 | 100 |
| 94 ThreadData::~ThreadData() {} | 101 ThreadData::~ThreadData() {} |
| 95 | 102 |
| 96 // static | 103 // static |
| 97 ThreadData* ThreadData::current() { | 104 ThreadData* ThreadData::current() { |
| 98 if (!tls_index_.initialized()) | 105 if (!tls_index_.initialized()) |
| 99 return NULL; | 106 return NULL; |
| 100 | 107 |
| 101 ThreadData* registry = static_cast<ThreadData*>(tls_index_.Get()); | 108 ThreadData* registry = static_cast<ThreadData*>(tls_index_.Get()); |
| 102 if (!registry) { | 109 if (!registry) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 output->append("<br>"); | 260 output->append("<br>"); |
| 254 subtotals.Write(output); | 261 subtotals.Write(output); |
| 255 output->append("<br><hr><br>"); | 262 output->append("<br><hr><br>"); |
| 256 subtotals.Clear(); | 263 subtotals.Clear(); |
| 257 } | 264 } |
| 258 } | 265 } |
| 259 } | 266 } |
| 260 } | 267 } |
| 261 | 268 |
| 262 Births* ThreadData::TallyABirth(const Location& location) { | 269 Births* ThreadData::TallyABirth(const Location& location) { |
| 263 if (!message_loop_) // In case message loop wasn't yet around... | 270 { |
| 264 message_loop_ = MessageLoop::current(); // Find it now. | 271 // This shouldn't use the MessageLoop::current() LazyInstance since this |
| 272 // might be used on a non-joinable thread. |
| 273 // http://crbug.com/62728 |
| 274 base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; |
| 275 if (!message_loop_) // In case message loop wasn't yet around... |
| 276 message_loop_ = MessageLoop::current(); // Find it now. |
| 277 } |
| 265 | 278 |
| 266 BirthMap::iterator it = birth_map_.find(location); | 279 BirthMap::iterator it = birth_map_.find(location); |
| 267 if (it != birth_map_.end()) { | 280 if (it != birth_map_.end()) { |
| 268 it->second->RecordBirth(); | 281 it->second->RecordBirth(); |
| 269 return it->second; | 282 return it->second; |
| 270 } | 283 } |
| 271 | 284 |
| 272 Births* tracker = new Births(location); | 285 Births* tracker = new Births(location); |
| 273 // Lock since the map may get relocated now, and other threads sometimes | 286 // Lock since the map may get relocated now, and other threads sometimes |
| 274 // snapshot it (but they lock before copying it). | 287 // snapshot it (but they lock before copying it). |
| 275 AutoLock lock(lock_); | 288 AutoLock lock(lock_); |
| 276 birth_map_[location] = tracker; | 289 birth_map_[location] = tracker; |
| 277 return tracker; | 290 return tracker; |
| 278 } | 291 } |
| 279 | 292 |
| 280 void ThreadData::TallyADeath(const Births& lifetimes, | 293 void ThreadData::TallyADeath(const Births& lifetimes, |
| 281 const TimeDelta& duration) { | 294 const TimeDelta& duration) { |
| 282 if (!message_loop_) // In case message loop wasn't yet around... | 295 { |
| 283 message_loop_ = MessageLoop::current(); // Find it now. | 296 // http://crbug.com/62728 |
| 297 base::ThreadRestrictions::ScopedAllowSingleton scoped_allow_singleton; |
| 298 if (!message_loop_) // In case message loop wasn't yet around... |
| 299 message_loop_ = MessageLoop::current(); // Find it now. |
| 300 } |
| 284 | 301 |
| 285 DeathMap::iterator it = death_map_.find(&lifetimes); | 302 DeathMap::iterator it = death_map_.find(&lifetimes); |
| 286 if (it != death_map_.end()) { | 303 if (it != death_map_.end()) { |
| 287 it->second.RecordDeath(duration); | 304 it->second.RecordDeath(duration); |
| 288 return; | 305 return; |
| 289 } | 306 } |
| 290 | 307 |
| 291 AutoLock lock(lock_); // Lock since the map may get relocated now. | 308 AutoLock lock(lock_); // Lock since the map may get relocated now. |
| 292 death_map_[&lifetimes].RecordDeath(duration); | 309 death_map_[&lifetimes].RecordDeath(duration); |
| 293 } | 310 } |
| (...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 (combined_selectors_ & BIRTH_THREAD) ? "*" : | 1049 (combined_selectors_ & BIRTH_THREAD) ? "*" : |
| 1033 sample.birth().birth_thread()->ThreadName().c_str(), | 1050 sample.birth().birth_thread()->ThreadName().c_str(), |
| 1034 (combined_selectors_ & DEATH_THREAD) ? "*" : | 1051 (combined_selectors_ & DEATH_THREAD) ? "*" : |
| 1035 sample.DeathThreadName().c_str()); | 1052 sample.DeathThreadName().c_str()); |
| 1036 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), | 1053 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), |
| 1037 !(combined_selectors_ & BIRTH_FUNCTION), | 1054 !(combined_selectors_ & BIRTH_FUNCTION), |
| 1038 output); | 1055 output); |
| 1039 } | 1056 } |
| 1040 | 1057 |
| 1041 } // namespace tracked_objects | 1058 } // namespace tracked_objects |
| OLD | NEW |