Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/tracked_objects.h" | 5 #include "base/tracked_objects.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <stdlib.h> | 8 #include <stdlib.h> |
| 9 | 9 |
| 10 #include "base/atomicops.h" | 10 #include "base/atomicops.h" |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 // ThreadData maintains the central data for all births and deaths on a single | 230 // ThreadData maintains the central data for all births and deaths on a single |
| 231 // thread. | 231 // thread. |
| 232 | 232 |
| 233 // TODO(jar): We should pull all these static vars together, into a struct, and | 233 // TODO(jar): We should pull all these static vars together, into a struct, and |
| 234 // optimize layout so that we benefit from locality of reference during accesses | 234 // optimize layout so that we benefit from locality of reference during accesses |
| 235 // to them. | 235 // to them. |
| 236 | 236 |
| 237 // static | 237 // static |
| 238 NowFunction* ThreadData::now_function_ = NULL; | 238 NowFunction* ThreadData::now_function_ = NULL; |
| 239 | 239 |
| 240 // static | |
| 241 bool ThreadData::now_function_is_time_ = false; | |
| 242 | |
| 240 // A TLS slot which points to the ThreadData instance for the current thread. We | 243 // A TLS slot which points to the ThreadData instance for the current thread. We |
| 241 // do a fake initialization here (zeroing out data), and then the real in-place | 244 // do a fake initialization here (zeroing out data), and then the real in-place |
| 242 // construction happens when we call tls_index_.Initialize(). | 245 // construction happens when we call tls_index_.Initialize(). |
| 243 // static | 246 // static |
| 244 base::ThreadLocalStorage::StaticSlot ThreadData::tls_index_ = TLS_INITIALIZER; | 247 base::ThreadLocalStorage::StaticSlot ThreadData::tls_index_ = TLS_INITIALIZER; |
| 245 | 248 |
| 246 // static | 249 // static |
| 247 int ThreadData::worker_thread_data_creation_count_ = 0; | 250 int ThreadData::worker_thread_data_creation_count_ = 0; |
| 248 | 251 |
| 249 // static | 252 // static |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 262 base::LazyInstance<base::Lock>::Leaky | 265 base::LazyInstance<base::Lock>::Leaky |
| 263 ThreadData::list_lock_ = LAZY_INSTANCE_INITIALIZER; | 266 ThreadData::list_lock_ = LAZY_INSTANCE_INITIALIZER; |
| 264 | 267 |
| 265 // static | 268 // static |
| 266 ThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED; | 269 ThreadData::Status ThreadData::status_ = ThreadData::UNINITIALIZED; |
| 267 | 270 |
| 268 ThreadData::ThreadData(const std::string& suggested_name) | 271 ThreadData::ThreadData(const std::string& suggested_name) |
| 269 : next_(NULL), | 272 : next_(NULL), |
| 270 next_retired_worker_(NULL), | 273 next_retired_worker_(NULL), |
| 271 worker_thread_number_(0), | 274 worker_thread_number_(0), |
| 272 incarnation_count_for_pool_(-1) { | 275 incarnation_count_for_pool_(-1), |
| 276 current_stopwatch_(NULL) { | |
| 273 DCHECK_GE(suggested_name.size(), 0u); | 277 DCHECK_GE(suggested_name.size(), 0u); |
| 274 thread_name_ = suggested_name; | 278 thread_name_ = suggested_name; |
| 275 PushToHeadOfList(); // Which sets real incarnation_count_for_pool_. | 279 PushToHeadOfList(); // Which sets real incarnation_count_for_pool_. |
| 276 } | 280 } |
| 277 | 281 |
| 278 ThreadData::ThreadData(int thread_number) | 282 ThreadData::ThreadData(int thread_number) |
| 279 : next_(NULL), | 283 : next_(NULL), |
| 280 next_retired_worker_(NULL), | 284 next_retired_worker_(NULL), |
| 281 worker_thread_number_(thread_number), | 285 worker_thread_number_(thread_number), |
| 282 incarnation_count_for_pool_(-1) { | 286 incarnation_count_for_pool_(-1), |
| 287 current_stopwatch_(NULL) { | |
| 283 CHECK_GT(thread_number, 0); | 288 CHECK_GT(thread_number, 0); |
| 284 base::StringAppendF(&thread_name_, "WorkerThread-%d", thread_number); | 289 base::StringAppendF(&thread_name_, "WorkerThread-%d", thread_number); |
| 285 PushToHeadOfList(); // Which sets real incarnation_count_for_pool_. | 290 PushToHeadOfList(); // Which sets real incarnation_count_for_pool_. |
| 286 } | 291 } |
| 287 | 292 |
| 288 ThreadData::~ThreadData() {} | 293 ThreadData::~ThreadData() {} |
| 289 | 294 |
| 290 void ThreadData::PushToHeadOfList() { | 295 void ThreadData::PushToHeadOfList() { |
| 291 // Toss in a hint of randomness (atop the uniniitalized value). | 296 // Toss in a hint of randomness (atop the uniniitalized value). |
| 292 (void)VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(&random_number_, | 297 (void)VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(&random_number_, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 base::AutoLock lock(map_lock_); | 432 base::AutoLock lock(map_lock_); |
| 428 parent_child_set_.insert(pair); | 433 parent_child_set_.insert(pair); |
| 429 } | 434 } |
| 430 } | 435 } |
| 431 | 436 |
| 432 return child; | 437 return child; |
| 433 } | 438 } |
| 434 | 439 |
| 435 void ThreadData::TallyADeath(const Births& birth, | 440 void ThreadData::TallyADeath(const Births& birth, |
| 436 int32 queue_duration, | 441 int32 queue_duration, |
| 437 int32 run_duration) { | 442 const TaskStopwatch& stopwatch) { |
| 443 int32 run_duration = stopwatch.RunDurationMs(); | |
| 444 | |
| 438 // Stir in some randomness, plus add constant in case durations are zero. | 445 // Stir in some randomness, plus add constant in case durations are zero. |
| 439 const int32 kSomePrimeNumber = 2147483647; | 446 const int32 kSomePrimeNumber = 2147483647; |
| 440 random_number_ += queue_duration + run_duration + kSomePrimeNumber; | 447 random_number_ += queue_duration + run_duration + kSomePrimeNumber; |
| 441 // An address is going to have some randomness to it as well ;-). | 448 // An address is going to have some randomness to it as well ;-). |
| 442 random_number_ ^= static_cast<int32>(&birth - reinterpret_cast<Births*>(0)); | 449 random_number_ ^= static_cast<int32>(&birth - reinterpret_cast<Births*>(0)); |
| 443 | 450 |
| 444 // We don't have queue durations without OS timer. OS timer is automatically | 451 // We don't have queue durations without OS timer. OS timer is automatically |
| 445 // used for task-post-timing, so the use of an alternate timer implies all | 452 // used for task-post-timing, so the use of an alternate timer implies all |
| 446 // queue times are invalid. | 453 // queue times are invalid, unless it was explicitly said that we can trust |
| 447 if (kAllowAlternateTimeSourceHandling && now_function_) | 454 // the alternate timer. |
| 455 if (kAllowAlternateTimeSourceHandling && | |
| 456 now_function_ && | |
| 457 !now_function_is_time_) { | |
| 448 queue_duration = 0; | 458 queue_duration = 0; |
| 459 } | |
| 449 | 460 |
| 450 DeathMap::iterator it = death_map_.find(&birth); | 461 DeathMap::iterator it = death_map_.find(&birth); |
| 451 DeathData* death_data; | 462 DeathData* death_data; |
| 452 if (it != death_map_.end()) { | 463 if (it != death_map_.end()) { |
| 453 death_data = &it->second; | 464 death_data = &it->second; |
| 454 } else { | 465 } else { |
| 455 base::AutoLock lock(map_lock_); // Lock as the map may get relocated now. | 466 base::AutoLock lock(map_lock_); // Lock as the map may get relocated now. |
| 456 death_data = &death_map_[&birth]; | 467 death_data = &death_map_[&birth]; |
| 457 } // Release lock ASAP. | 468 } // Release lock ASAP. |
| 458 death_data->RecordDeath(queue_duration, run_duration, random_number_); | 469 death_data->RecordDeath(queue_duration, run_duration, random_number_); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 474 return NULL; | 485 return NULL; |
| 475 ThreadData* current_thread_data = Get(); | 486 ThreadData* current_thread_data = Get(); |
| 476 if (!current_thread_data) | 487 if (!current_thread_data) |
| 477 return NULL; | 488 return NULL; |
| 478 return current_thread_data->TallyABirth(location); | 489 return current_thread_data->TallyABirth(location); |
| 479 } | 490 } |
| 480 | 491 |
| 481 // static | 492 // static |
| 482 void ThreadData::TallyRunOnNamedThreadIfTracking( | 493 void ThreadData::TallyRunOnNamedThreadIfTracking( |
| 483 const base::TrackingInfo& completed_task, | 494 const base::TrackingInfo& completed_task, |
| 484 const TrackedTime& start_of_run, | 495 const TaskStopwatch& stopwatch) { |
| 485 const TrackedTime& end_of_run) { | |
| 486 if (!kTrackAllTaskObjects) | 496 if (!kTrackAllTaskObjects) |
| 487 return; // Not compiled in. | 497 return; // Not compiled in. |
| 488 | 498 |
| 489 // Even if we have been DEACTIVATED, we will process any pending births so | 499 // Even if we have been DEACTIVATED, we will process any pending births so |
| 490 // that our data structures (which counted the outstanding births) remain | 500 // that our data structures (which counted the outstanding births) remain |
| 491 // consistent. | 501 // consistent. |
| 492 const Births* birth = completed_task.birth_tally; | 502 const Births* birth = completed_task.birth_tally; |
| 493 if (!birth) | 503 if (!birth) |
| 494 return; | 504 return; |
| 495 ThreadData* current_thread_data = Get(); | 505 ThreadData* current_thread_data = stopwatch.GetThreadData(); |
| 496 if (!current_thread_data) | 506 if (!current_thread_data) |
| 497 return; | 507 return; |
| 498 | 508 |
| 499 // Watch out for a race where status_ is changing, and hence one or both | 509 // Watch out for a race where status_ is changing, and hence one or both |
| 500 // of start_of_run or end_of_run is zero. In that case, we didn't bother to | 510 // of start_of_run or end_of_run is zero. In that case, we didn't bother to |
| 501 // get a time value since we "weren't tracking" and we were trying to be | 511 // get a time value since we "weren't tracking" and we were trying to be |
| 502 // efficient by not calling for a genuine time value. For simplicity, we'll | 512 // efficient by not calling for a genuine time value. For simplicity, we'll |
| 503 // use a default zero duration when we can't calculate a true value. | 513 // use a default zero duration when we can't calculate a true value. |
| 514 TrackedTime start_of_run = stopwatch.StartTime(); | |
| 504 int32 queue_duration = 0; | 515 int32 queue_duration = 0; |
| 505 int32 run_duration = 0; | |
| 506 if (!start_of_run.is_null()) { | 516 if (!start_of_run.is_null()) { |
| 507 queue_duration = (start_of_run - completed_task.EffectiveTimePosted()) | 517 queue_duration = (start_of_run - completed_task.EffectiveTimePosted()) |
| 508 .InMilliseconds(); | 518 .InMilliseconds(); |
| 509 if (!end_of_run.is_null()) | |
| 510 run_duration = (end_of_run - start_of_run).InMilliseconds(); | |
| 511 } | 519 } |
| 512 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); | 520 current_thread_data->TallyADeath(*birth, queue_duration, stopwatch); |
| 513 } | 521 } |
| 514 | 522 |
| 515 // static | 523 // static |
| 516 void ThreadData::TallyRunOnWorkerThreadIfTracking( | 524 void ThreadData::TallyRunOnWorkerThreadIfTracking( |
| 517 const Births* birth, | 525 const Births* birth, |
| 518 const TrackedTime& time_posted, | 526 const TrackedTime& time_posted, |
| 519 const TrackedTime& start_of_run, | 527 const TaskStopwatch& stopwatch) { |
| 520 const TrackedTime& end_of_run) { | |
| 521 if (!kTrackAllTaskObjects) | 528 if (!kTrackAllTaskObjects) |
| 522 return; // Not compiled in. | 529 return; // Not compiled in. |
| 523 | 530 |
| 524 // Even if we have been DEACTIVATED, we will process any pending births so | 531 // Even if we have been DEACTIVATED, we will process any pending births so |
| 525 // that our data structures (which counted the outstanding births) remain | 532 // that our data structures (which counted the outstanding births) remain |
| 526 // consistent. | 533 // consistent. |
| 527 if (!birth) | 534 if (!birth) |
| 528 return; | 535 return; |
| 529 | 536 |
| 530 // TODO(jar): Support the option to coalesce all worker-thread activity under | 537 // TODO(jar): Support the option to coalesce all worker-thread activity under |
| 531 // one ThreadData instance that uses locks to protect *all* access. This will | 538 // one ThreadData instance that uses locks to protect *all* access. This will |
| 532 // reduce memory (making it provably bounded), but run incrementally slower | 539 // reduce memory (making it provably bounded), but run incrementally slower |
| 533 // (since we'll use locks on TallyABirth and TallyADeath). The good news is | 540 // (since we'll use locks on TallyABirth and TallyADeath). The good news is |
| 534 // that the locks on TallyADeath will be *after* the worker thread has run, | 541 // that the locks on TallyADeath will be *after* the worker thread has run, |
| 535 // and hence nothing will be waiting for the completion (... besides some | 542 // and hence nothing will be waiting for the completion (... besides some |
| 536 // other thread that might like to run). Also, the worker threads tasks are | 543 // other thread that might like to run). Also, the worker threads tasks are |
| 537 // generally longer, and hence the cost of the lock may perchance be amortized | 544 // generally longer, and hence the cost of the lock may perchance be amortized |
| 538 // over the long task's lifetime. | 545 // over the long task's lifetime. |
| 539 ThreadData* current_thread_data = Get(); | 546 ThreadData* current_thread_data = stopwatch.GetThreadData(); |
| 540 if (!current_thread_data) | 547 if (!current_thread_data) |
| 541 return; | 548 return; |
| 542 | 549 |
| 550 TrackedTime start_of_run = stopwatch.StartTime(); | |
| 543 int32 queue_duration = 0; | 551 int32 queue_duration = 0; |
| 544 int32 run_duration = 0; | |
| 545 if (!start_of_run.is_null()) { | 552 if (!start_of_run.is_null()) { |
| 546 queue_duration = (start_of_run - time_posted).InMilliseconds(); | 553 queue_duration = (start_of_run - time_posted).InMilliseconds(); |
| 547 if (!end_of_run.is_null()) | |
| 548 run_duration = (end_of_run - start_of_run).InMilliseconds(); | |
| 549 } | 554 } |
| 550 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); | 555 current_thread_data->TallyADeath(*birth, queue_duration, stopwatch); |
| 551 } | 556 } |
| 552 | 557 |
| 553 // static | 558 // static |
| 554 void ThreadData::TallyRunInAScopedRegionIfTracking( | 559 void ThreadData::TallyRunInAScopedRegionIfTracking( |
| 555 const Births* birth, | 560 const Births* birth, |
| 556 const TrackedTime& start_of_run, | 561 const TaskStopwatch& stopwatch) { |
| 557 const TrackedTime& end_of_run) { | |
| 558 if (!kTrackAllTaskObjects) | 562 if (!kTrackAllTaskObjects) |
| 559 return; // Not compiled in. | 563 return; // Not compiled in. |
| 560 | 564 |
| 561 // Even if we have been DEACTIVATED, we will process any pending births so | 565 // Even if we have been DEACTIVATED, we will process any pending births so |
| 562 // that our data structures (which counted the outstanding births) remain | 566 // that our data structures (which counted the outstanding births) remain |
| 563 // consistent. | 567 // consistent. |
| 564 if (!birth) | 568 if (!birth) |
| 565 return; | 569 return; |
| 566 | 570 |
| 567 ThreadData* current_thread_data = Get(); | 571 ThreadData* current_thread_data = stopwatch.GetThreadData(); |
| 568 if (!current_thread_data) | 572 if (!current_thread_data) |
| 569 return; | 573 return; |
| 570 | 574 |
| 571 int32 queue_duration = 0; | 575 int32 queue_duration = 0; |
| 572 int32 run_duration = 0; | 576 current_thread_data->TallyADeath(*birth, queue_duration, stopwatch); |
| 573 if (!start_of_run.is_null() && !end_of_run.is_null()) | |
| 574 run_duration = (end_of_run - start_of_run).InMilliseconds(); | |
| 575 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); | |
| 576 } | 577 } |
| 577 | 578 |
| 578 // static | 579 // static |
| 579 void ThreadData::SnapshotAllExecutedTasks(bool reset_max, | 580 void ThreadData::SnapshotAllExecutedTasks(bool reset_max, |
| 580 ProcessDataSnapshot* process_data, | 581 ProcessDataSnapshot* process_data, |
| 581 BirthCountMap* birth_counts) { | 582 BirthCountMap* birth_counts) { |
| 582 if (!kTrackAllTaskObjects) | 583 if (!kTrackAllTaskObjects) |
| 583 return; // Not compiled in. | 584 return; // Not compiled in. |
| 584 | 585 |
| 585 // Get an unchanging copy of a ThreadData list. | 586 // Get an unchanging copy of a ThreadData list. |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 751 bool ThreadData::TrackingStatus() { | 752 bool ThreadData::TrackingStatus() { |
| 752 return status_ > DEACTIVATED; | 753 return status_ > DEACTIVATED; |
| 753 } | 754 } |
| 754 | 755 |
| 755 // static | 756 // static |
| 756 bool ThreadData::TrackingParentChildStatus() { | 757 bool ThreadData::TrackingParentChildStatus() { |
| 757 return status_ >= PROFILING_CHILDREN_ACTIVE; | 758 return status_ >= PROFILING_CHILDREN_ACTIVE; |
| 758 } | 759 } |
| 759 | 760 |
| 760 // static | 761 // static |
| 761 TrackedTime ThreadData::NowForStartOfRun(const Births* parent) { | 762 void ThreadData::PrepareForStartOfRun(const Births* parent) { |
| 762 if (kTrackParentChildLinks && parent && status_ > PROFILING_ACTIVE) { | 763 if (kTrackParentChildLinks && parent && status_ > PROFILING_ACTIVE) { |
| 763 ThreadData* current_thread_data = Get(); | 764 ThreadData* current_thread_data = Get(); |
|
jar (doing other things)
2014/09/05 04:36:05
I liked the way you replaced several other Get() c
vadimt
2014/09/05 20:25:55
My understanding is that parent-child tracking is
| |
| 764 if (current_thread_data) | 765 if (current_thread_data) |
| 765 current_thread_data->parent_stack_.push(parent); | 766 current_thread_data->parent_stack_.push(parent); |
| 766 } | 767 } |
| 767 return Now(); | |
| 768 } | 768 } |
| 769 | 769 |
| 770 // static | 770 // static |
| 771 TrackedTime ThreadData::NowForEndOfRun() { | |
| 772 return Now(); | |
| 773 } | |
| 774 | |
| 775 // static | |
| 776 void ThreadData::SetAlternateTimeSource(NowFunction* now_function) { | 771 void ThreadData::SetAlternateTimeSource(NowFunction* now_function) { |
| 777 DCHECK(now_function); | 772 DCHECK(now_function); |
| 778 if (kAllowAlternateTimeSourceHandling) | 773 if (kAllowAlternateTimeSourceHandling) |
| 779 now_function_ = now_function; | 774 now_function_ = now_function; |
| 780 } | 775 } |
| 781 | 776 |
| 782 // static | 777 // static |
| 783 TrackedTime ThreadData::Now() { | 778 TrackedTime ThreadData::Now() { |
| 784 if (kAllowAlternateTimeSourceHandling && now_function_) | 779 if (kAllowAlternateTimeSourceHandling && now_function_) |
| 785 return TrackedTime::FromMilliseconds((*now_function_)()); | 780 return TrackedTime::FromMilliseconds((*now_function_)()); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 851 thread_data_list = thread_data_list->next(); | 846 thread_data_list = thread_data_list->next(); |
| 852 | 847 |
| 853 for (BirthMap::iterator it = next_thread_data->birth_map_.begin(); | 848 for (BirthMap::iterator it = next_thread_data->birth_map_.begin(); |
| 854 next_thread_data->birth_map_.end() != it; ++it) | 849 next_thread_data->birth_map_.end() != it; ++it) |
| 855 delete it->second; // Delete the Birth Records. | 850 delete it->second; // Delete the Birth Records. |
| 856 delete next_thread_data; // Includes all Death Records. | 851 delete next_thread_data; // Includes all Death Records. |
| 857 } | 852 } |
| 858 } | 853 } |
| 859 | 854 |
| 860 //------------------------------------------------------------------------------ | 855 //------------------------------------------------------------------------------ |
| 856 TaskStopwatch::TaskStopwatch() | |
| 857 : start_time_(ThreadData::Now()), | |
| 858 current_thread_data_(ThreadData::Get()), | |
| 859 excluded_duration_ms_(0), | |
| 860 parent_stopwatch_(NULL) { | |
| 861 #ifndef NDEBUG | |
| 862 state_ = RUNNING; | |
| 863 running_child_ = NULL; | |
| 864 #endif | |
| 865 | |
| 866 wallclock_duration_ms_ = 0; | |
| 867 if (!current_thread_data_) | |
| 868 return; | |
| 869 | |
| 870 parent_stopwatch_ = current_thread_data_->current_stopwatch_; | |
| 871 #ifndef NDEBUG | |
| 872 if (parent_stopwatch_) { | |
| 873 DCHECK(parent_stopwatch_->state_ == RUNNING); | |
| 874 DCHECK(parent_stopwatch_->running_child_ == NULL); | |
| 875 parent_stopwatch_->running_child_ = this; | |
| 876 } | |
| 877 #endif | |
| 878 current_thread_data_->current_stopwatch_ = this; | |
| 879 } | |
| 880 | |
| 881 TaskStopwatch::~TaskStopwatch() { | |
| 882 #ifndef NDEBUG | |
|
jar (doing other things)
2014/09/05 04:36:05
nit: We probably don't need the ifdef around DCHEC
vadimt
2014/09/05 20:25:55
We actually need it, since otherwise we get compil
| |
| 883 DCHECK(state_ != RUNNING); | |
| 884 DCHECK(running_child_ == NULL); | |
| 885 #endif | |
| 886 } | |
| 887 | |
| 888 void TaskStopwatch::Stop() { | |
| 889 const TrackedTime end_time = ThreadData::Now(); | |
| 890 #ifndef NDEBUG | |
| 891 DCHECK(state_ == RUNNING); | |
| 892 state_ = STOPPED; | |
| 893 DCHECK(running_child_ == NULL); | |
| 894 #endif | |
| 895 | |
| 896 if (!start_time_.is_null() && !end_time.is_null()) { | |
| 897 wallclock_duration_ms_ = (end_time - start_time_).InMilliseconds(); | |
| 898 } | |
| 899 | |
| 900 if (!current_thread_data_) | |
| 901 return; | |
| 902 | |
| 903 DCHECK(current_thread_data_->current_stopwatch_ == this); | |
| 904 current_thread_data_->current_stopwatch_ = parent_stopwatch_; | |
| 905 if (!parent_stopwatch_) | |
| 906 return; | |
| 907 | |
| 908 #ifndef NDEBUG | |
| 909 DCHECK(parent_stopwatch_->state_ == RUNNING); | |
| 910 DCHECK(parent_stopwatch_->running_child_ == this); | |
| 911 parent_stopwatch_->running_child_ = NULL; | |
| 912 #endif | |
| 913 parent_stopwatch_->excluded_duration_ms_ += | |
| 914 wallclock_duration_ms_; | |
| 915 parent_stopwatch_ = NULL; | |
| 916 } | |
| 917 | |
| 918 TrackedTime TaskStopwatch::StartTime() const { | |
| 919 return start_time_; | |
| 920 } | |
| 921 | |
| 922 int32 TaskStopwatch::RunDurationMs() const { | |
| 923 #ifndef NDEBUG | |
| 924 DCHECK(state_ == STOPPED); | |
| 925 #endif | |
| 926 | |
| 927 return wallclock_duration_ms_ - excluded_duration_ms_; | |
| 928 } | |
| 929 | |
| 930 ThreadData* TaskStopwatch::GetThreadData() const { | |
| 931 return current_thread_data_; | |
| 932 } | |
| 933 | |
| 934 //------------------------------------------------------------------------------ | |
| 861 TaskSnapshot::TaskSnapshot() { | 935 TaskSnapshot::TaskSnapshot() { |
| 862 } | 936 } |
| 863 | 937 |
| 864 TaskSnapshot::TaskSnapshot(const BirthOnThread& birth, | 938 TaskSnapshot::TaskSnapshot(const BirthOnThread& birth, |
| 865 const DeathData& death_data, | 939 const DeathData& death_data, |
| 866 const std::string& death_thread_name) | 940 const std::string& death_thread_name) |
| 867 : birth(birth), | 941 : birth(birth), |
| 868 death_data(death_data), | 942 death_data(death_data), |
| 869 death_thread_name(death_thread_name) { | 943 death_thread_name(death_thread_name) { |
| 870 } | 944 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 895 : process_id(base::GetCurrentProcId()) { | 969 : process_id(base::GetCurrentProcId()) { |
| 896 #else | 970 #else |
| 897 : process_id(0) { | 971 : process_id(0) { |
| 898 #endif | 972 #endif |
| 899 } | 973 } |
| 900 | 974 |
| 901 ProcessDataSnapshot::~ProcessDataSnapshot() { | 975 ProcessDataSnapshot::~ProcessDataSnapshot() { |
| 902 } | 976 } |
| 903 | 977 |
| 904 } // namespace tracked_objects | 978 } // namespace tracked_objects |
| OLD | NEW |