Chromium Code Reviews| 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 |
|
ramant (doing other things)
2012/02/15 18:33:46
nit: try -> true
jar (doing other things)
2012/02/15 20:26:32
Done. I added a lot of text to try to be even cle
|
| +// 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"; |
|
ramant (doing other things)
2012/02/15 18:33:46
nit: should we consider commenting that "k_alterna
jar (doing other things)
2012/02/15 20:26:32
I went back and tried to move it to shared place.
|
| + |
| } // 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); |
|
ramant (doing other things)
2012/02/15 18:33:46
nit: should we consider moving the following check
jar (doing other things)
2012/02/15 20:26:32
Done.
|
| + 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. |
|
ramant (doing other things)
2012/02/15 18:33:46
Wondered if "_heap_init" happens before ThreadData
jar (doing other things)
2012/02/15 20:26:32
heap_init is run super-duper-early, before *any* a
|
| + 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. |