| Index: base/tracked_objects.cc
|
| ===================================================================
|
| --- base/tracked_objects.cc (revision 120802)
|
| +++ base/tracked_objects.cc (working copy)
|
| @@ -8,6 +8,7 @@
|
|
|
| #include "base/format_macros.h"
|
| #include "base/message_loop.h"
|
| +#include "base/profiler/alternate_timer.h"
|
| #include "base/stringprintf.h"
|
| #include "base/third_party/valgrind/memcheck.h"
|
| #include "base/threading/thread_restrictions.h"
|
| @@ -35,6 +36,17 @@
|
| const ThreadData::Status kInitialStartupState =
|
| ThreadData::PROFILING_CHILDREN_ACTIVE;
|
|
|
| +// Control whether an alternate time source (Now() function) is supported by
|
| +// the ThreadData class. This compile time flag should be set to try if we want
|
| +// other modules, such as an allocator, to call with a new thread-specific
|
| +// Now() function to use (instead of of calling into tracked_time).
|
| +static const bool kAllowAlternateTimeSourceHandling = true;
|
| +
|
| +// Environment variable name that is used to activate alternate timer profiling
|
| +// (such as using TCMalloc allocations to provide a pseudo-timer) for tasks
|
| +// instead of wall clock profiling.
|
| +static const char k_alternate_profile_timer[] = "CHROME_PROFILER_TIME";
|
| +
|
| } // namespace
|
|
|
| //------------------------------------------------------------------------------
|
| @@ -176,6 +188,9 @@
|
| // optimize layout so that we benefit from locality of reference during accesses
|
| // to them.
|
|
|
| +// static
|
| +NowFunction* ThreadData::now_function_ = NULL;
|
| +
|
| // A TLS slot which points to the ThreadData instance for the current thread. We
|
| // do a fake initialization here (zeroing out data), and then the real in-place
|
| // construction happens when we call tls_index_.Initialize().
|
| @@ -370,6 +385,12 @@
|
| // An address is going to have some randomness to it as well ;-).
|
| random_number_ ^= static_cast<int32>(&birth - reinterpret_cast<Births*>(0));
|
|
|
| + // We don't have queue durations without OS timer. OS timer is automatically
|
| + // used for task-post-timing, so the use of an alternate timer implies all
|
| + // queue times are invalid.
|
| + if (kAllowAlternateTimeSourceHandling && now_function_)
|
| + queue_duration = 0;
|
| +
|
| DeathMap::iterator it = death_map_.find(&birth);
|
| DeathData* death_data;
|
| if (it != death_map_.end()) {
|
| @@ -579,6 +600,28 @@
|
| it->second->Clear();
|
| }
|
|
|
| +static void OptionallyInitializeAlternateTimer() {
|
| + char* alternate_selector = getenv(k_alternate_profile_timer);
|
| + if (!alternate_selector)
|
| + return;
|
| + switch (*alternate_selector) {
|
| + case '0': // This is the default value, and uses the wall clock time.
|
| + break;
|
| + case '1': {
|
| + // Use the TCMalloc allocations-on-thread as a pseudo-time.
|
| + NowFunction* now_function = GetAlternateTimeSource();
|
| + if (!now_function)
|
| + break;
|
| + ThreadData::SetAlternateTimeSource(now_function);
|
| + break;
|
| + }
|
| +
|
| + default:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +}
|
| +
|
| bool ThreadData::Initialize() {
|
| if (!kTrackAllTaskObjects)
|
| return false; // Not compiled in.
|
| @@ -594,6 +637,13 @@
|
| if (status_ >= DEACTIVATED)
|
| return true; // Someone raced in here and beat us.
|
|
|
| + // Put an alternate timer in place if the environment calls for it, such as
|
| + // for tracking TCMalloc allocations. This insertion is idempotent, so we
|
| + // don't mind if there is a race, and we'd prefer not to be in a lock while
|
| + // doing this work.
|
| + if (kAllowAlternateTimeSourceHandling)
|
| + OptionallyInitializeAlternateTimer();
|
| +
|
| // Perform the "real" TLS initialization now, and leave it intact through
|
| // process termination.
|
| if (!tls_index_.initialized()) { // Testing may have initialized this.
|
| @@ -666,7 +716,15 @@
|
| }
|
|
|
| // static
|
| +void ThreadData::SetAlternateTimeSource(NowFunction* now_function) {
|
| + if (kAllowAlternateTimeSourceHandling)
|
| + now_function_ = now_function;
|
| +}
|
| +
|
| +// static
|
| TrackedTime ThreadData::Now() {
|
| + if (kAllowAlternateTimeSourceHandling && now_function_)
|
| + return TrackedTime::FromMilliseconds((*now_function_)());
|
| if (kTrackAllTaskObjects && TrackingStatus())
|
| return TrackedTime::Now();
|
| return TrackedTime(); // Super fast when disabled, or not compiled.
|
|
|