Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(629)

Side by Side Diff: base/tracked_objects.cc

Issue 8414050: Pile of nits for tracked object enablement (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/chrome_browser_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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"
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 void ThreadData::OnThreadTerminationCleanup() const { 213 void ThreadData::OnThreadTerminationCleanup() const {
214 tls_index_.Set(NULL); 214 tls_index_.Set(NULL);
215 if (!is_a_worker_thread_) 215 if (!is_a_worker_thread_)
216 return; 216 return;
217 base::AutoLock lock(*list_lock_); 217 base::AutoLock lock(*list_lock_);
218 unregistered_thread_data_pool_->push(this); 218 unregistered_thread_data_pool_->push(this);
219 } 219 }
220 220
221 // static 221 // static
222 void ThreadData::WriteHTML(const std::string& query, std::string* output) { 222 void ThreadData::WriteHTML(const std::string& query, std::string* output) {
223 if (!ThreadData::tracking_status()) 223 if (status_ == UNINITIALIZED)
224 return; // Not yet initialized. 224 return; // Not yet initialized.
225 225
226 DataCollector collected_data; // Gather data. 226 DataCollector collected_data; // Gather data.
227 collected_data.AddListOfLivingObjects(); // Add births that are still alive. 227 collected_data.AddListOfLivingObjects(); // Add births that are still alive.
228 228
229 // Data Gathering is complete. Now to sort/process/render. 229 // Data Gathering is complete. Now to sort/process/render.
230 DataCollector::Collection* collection = collected_data.collection(); 230 DataCollector::Collection* collection = collected_data.collection();
231 231
232 // Create filtering and sort comparison object. 232 // Create filtering and sort comparison object.
233 Comparator comparator; 233 Comparator comparator;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 // To avoid conflating our stats with the delay duration in a PostDelayedTask, 399 // To avoid conflating our stats with the delay duration in a PostDelayedTask,
400 // we identify such tasks, and replace their post_time with the time they 400 // we identify such tasks, and replace their post_time with the time they
401 // were scheduled (requested?) to emerge from the delayed task queue. This 401 // were scheduled (requested?) to emerge from the delayed task queue. This
402 // means that queueing delay for such tasks will show how long they went 402 // means that queueing delay for such tasks will show how long they went
403 // unserviced, after they *could* be serviced. This is the same stat as we 403 // unserviced, after they *could* be serviced. This is the same stat as we
404 // have for non-delayed tasks, and we consistently call it queueing delay. 404 // have for non-delayed tasks, and we consistently call it queueing delay.
405 TrackedTime effective_post_time = completed_task.delayed_run_time.is_null() 405 TrackedTime effective_post_time = completed_task.delayed_run_time.is_null()
406 ? tracked_objects::TrackedTime(completed_task.time_posted) 406 ? tracked_objects::TrackedTime(completed_task.time_posted)
407 : tracked_objects::TrackedTime(completed_task.delayed_run_time); 407 : tracked_objects::TrackedTime(completed_task.delayed_run_time);
408 408
409 Duration queue_duration = start_of_run - effective_post_time; 409 // Watch out for a race where status_ is changing, and hence one or both
410 Duration run_duration = end_of_run - start_of_run; 410 // of start_of_run or end_of_run is zero. IN that case, we didn't bother to
411 // get a time value since we "weren't tracking" and we were trying to be
412 // efficient by not calling for a genuine time value. For simplicity, we'll
413 // use a default zero duration when we can't calculate a true value.
414 Duration queue_duration;
415 Duration run_duration;
416 if (!start_of_run.is_null()) {
417 queue_duration = start_of_run - effective_post_time;
418 if (!end_of_run.is_null())
419 run_duration = end_of_run - start_of_run;
420 }
411 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); 421 current_thread_data->TallyADeath(*birth, queue_duration, run_duration);
412 } 422 }
413 423
414 // static 424 // static
415 void ThreadData::TallyRunOnWorkerThreadIfTracking( 425 void ThreadData::TallyRunOnWorkerThreadIfTracking(
416 const Births* birth, 426 const Births* birth,
417 const TrackedTime& time_posted, 427 const TrackedTime& time_posted,
418 const TrackedTime& start_of_run, 428 const TrackedTime& start_of_run,
419 const TrackedTime& end_of_run) { 429 const TrackedTime& end_of_run) {
420 if (!kTrackAllTaskObjects) 430 if (!kTrackAllTaskObjects)
(...skipping 11 matching lines...) Expand all
432 // (since we'll use locks on TallyBirth and TallyDeath). The good news is 442 // (since we'll use locks on TallyBirth and TallyDeath). The good news is
433 // that the locks on TallyDeath will be *after* the worker thread has run, and 443 // that the locks on TallyDeath will be *after* the worker thread has run, and
434 // hence nothing will be waiting for the completion (... besides some other 444 // hence nothing will be waiting for the completion (... besides some other
435 // thread that might like to run). Also, the worker threads tasks are 445 // thread that might like to run). Also, the worker threads tasks are
436 // generally longer, and hence the cost of the lock may perchance be amortized 446 // generally longer, and hence the cost of the lock may perchance be amortized
437 // over the long task's lifetime. 447 // over the long task's lifetime.
438 ThreadData* current_thread_data = Get(); 448 ThreadData* current_thread_data = Get();
439 if (!current_thread_data) 449 if (!current_thread_data)
440 return; 450 return;
441 451
442 Duration queue_duration = start_of_run - time_posted; 452 Duration queue_duration;
443 Duration run_duration = end_of_run - start_of_run; 453 Duration run_duration;
454 if (!start_of_run.is_null()) {
455 queue_duration = start_of_run - time_posted;
456 if (!end_of_run.is_null())
457 run_duration = end_of_run - start_of_run;
458 }
444 current_thread_data->TallyADeath(*birth, queue_duration, run_duration); 459 current_thread_data->TallyADeath(*birth, queue_duration, run_duration);
445 } 460 }
446 461
447 // static 462 // static
448 ThreadData* ThreadData::first() { 463 ThreadData* ThreadData::first() {
449 base::AutoLock lock(*list_lock_); 464 base::AutoLock lock(*list_lock_);
450 return all_thread_data_list_head_; 465 return all_thread_data_list_head_;
451 } 466 }
452 467
453 // This may be called from another thread. 468 // This may be called from another thread.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 return true; 532 return true;
518 } 533 }
519 534
520 // static 535 // static
521 bool ThreadData::tracking_status() { 536 bool ThreadData::tracking_status() {
522 return status_ == ACTIVE; 537 return status_ == ACTIVE;
523 } 538 }
524 539
525 // static 540 // static
526 TrackedTime ThreadData::Now() { 541 TrackedTime ThreadData::Now() {
527 if (!kTrackAllTaskObjects || status_ != ACTIVE) 542 if (kTrackAllTaskObjects && tracking_status())
528 return TrackedTime(); // Super fast when disabled, or not compiled. 543 return TrackedTime::Now();
529 return TrackedTime::Now(); 544 return TrackedTime(); // Super fast when disabled, or not compiled.
530 } 545 }
531 546
532 // static 547 // static
533 void ThreadData::ShutdownSingleThreadedCleanup() { 548 void ThreadData::ShutdownSingleThreadedCleanup() {
534 // This is only called from test code, where we need to cleanup so that 549 // This is only called from test code, where we need to cleanup so that
535 // additional tests can be run. 550 // additional tests can be run.
536 // We must be single threaded... but be careful anyway. 551 // We must be single threaded... but be careful anyway.
537 if (!InitializeAndSetTrackingStatus(false)) 552 if (!InitializeAndSetTrackingStatus(false))
538 return; 553 return;
539 ThreadData* thread_data_list; 554 ThreadData* thread_data_list;
540 ThreadDataPool* final_pool; 555 ThreadDataPool* final_pool;
541 { 556 {
542 base::AutoLock lock(*list_lock_); 557 base::AutoLock lock(*list_lock_);
543 thread_data_list = all_thread_data_list_head_; 558 thread_data_list = all_thread_data_list_head_;
544 all_thread_data_list_head_ = NULL; 559 all_thread_data_list_head_ = NULL;
545 final_pool = unregistered_thread_data_pool_; 560 final_pool = unregistered_thread_data_pool_;
546 unregistered_thread_data_pool_ = NULL; 561 unregistered_thread_data_pool_ = NULL;
547 } 562 }
548 563
564 // Put most global static back in pristine shape.
565 thread_number_counter_ = 0;
566 tls_index_.Set(NULL);
567 status_ = UNINITIALIZED;
568
569 // To avoid any chance of racing in unit tests, which is the only place we
570 // call this function, we will leak all the data structures we recovered.
571 // These structures could plausibly be used by other threads in earlier tests
572 // that are still running.
573 return;
574
575 // If we wanted to cleanup (on a single thread), here is what we would do.
576
549 if (final_pool) { 577 if (final_pool) {
550 // The thread_data_list contains *all* the instances, and we'll use it to 578 // The thread_data_list contains *all* the instances, and we'll use it to
551 // delete them. This pool has pointers to some instances, and we just 579 // delete them. This pool has pointers to some instances, and we just
552 // have to drop those pointers (and not do the deletes here). 580 // have to drop those pointers (and not do the deletes here).
553 while (!final_pool->empty()) 581 while (!final_pool->empty())
554 final_pool->pop(); 582 final_pool->pop();
555 delete final_pool; 583 delete final_pool;
556 } 584 }
557 585
558 // Do actual recursive delete in all ThreadData instances. 586 // Do actual recursive delete in all ThreadData instances.
559 while (thread_data_list) { 587 while (thread_data_list) {
560 ThreadData* next_thread_data = thread_data_list; 588 ThreadData* next_thread_data = thread_data_list;
561 thread_data_list = thread_data_list->next(); 589 thread_data_list = thread_data_list->next();
562 590
563 for (BirthMap::iterator it = next_thread_data->birth_map_.begin(); 591 for (BirthMap::iterator it = next_thread_data->birth_map_.begin();
564 next_thread_data->birth_map_.end() != it; ++it) 592 next_thread_data->birth_map_.end() != it; ++it)
565 delete it->second; // Delete the Birth Records. 593 delete it->second; // Delete the Birth Records.
566 next_thread_data->birth_map_.clear(); 594 next_thread_data->birth_map_.clear();
567 next_thread_data->death_map_.clear(); 595 next_thread_data->death_map_.clear();
568 delete next_thread_data; // Includes all Death Records. 596 delete next_thread_data; // Includes all Death Records.
569 } 597 }
570 // Put most global static back in pristine shape.
571 thread_number_counter_ = 0;
572 tls_index_.Set(NULL);
573 status_ = UNINITIALIZED;
574 } 598 }
575 599
576 //------------------------------------------------------------------------------ 600 //------------------------------------------------------------------------------
577 // Individual 3-tuple of birth (place and thread) along with death thread, and 601 // Individual 3-tuple of birth (place and thread) along with death thread, and
578 // the accumulated stats for instances (DeathData). 602 // the accumulated stats for instances (DeathData).
579 603
580 Snapshot::Snapshot(const BirthOnThread& birth_on_thread, 604 Snapshot::Snapshot(const BirthOnThread& birth_on_thread,
581 const ThreadData& death_thread, 605 const ThreadData& death_thread,
582 const DeathData& death_data) 606 const DeathData& death_data)
583 : birth_(&birth_on_thread), 607 : birth_(&birth_on_thread),
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 (combined_selectors_ & BIRTH_THREAD) ? "*" : 1138 (combined_selectors_ & BIRTH_THREAD) ? "*" :
1115 sample.birth().birth_thread()->thread_name().c_str(), 1139 sample.birth().birth_thread()->thread_name().c_str(),
1116 (combined_selectors_ & DEATH_THREAD) ? "*" : 1140 (combined_selectors_ & DEATH_THREAD) ? "*" :
1117 sample.DeathThreadName().c_str()); 1141 sample.DeathThreadName().c_str());
1118 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE), 1142 sample.birth().location().Write(!(combined_selectors_ & BIRTH_FILE),
1119 !(combined_selectors_ & BIRTH_FUNCTION), 1143 !(combined_selectors_ & BIRTH_FUNCTION),
1120 output); 1144 output);
1121 } 1145 }
1122 1146
1123 } // namespace tracked_objects 1147 } // namespace tracked_objects
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/chrome_browser_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698