Index: base/debug/task_annotator.cc |
diff --git a/base/debug/task_annotator.cc b/base/debug/task_annotator.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c6576c829e83f1bb2bf4a2209afdd4a9b4e3f5e9 |
--- /dev/null |
+++ b/base/debug/task_annotator.cc |
@@ -0,0 +1,74 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/debug/task_annotator.h" |
+ |
+#include "base/debug/alias.h" |
+#include "base/debug/trace_event.h" |
+#include "base/pending_task.h" |
+#include "base/tracked_objects.h" |
+ |
+namespace base { |
+namespace debug { |
+ |
+TaskAnnotator::TaskAnnotator() { |
+} |
+ |
+TaskAnnotator::~TaskAnnotator() { |
+} |
+ |
+void TaskAnnotator::DidQueueTask(const char* queue_function, |
+ const PendingTask& pending_task) { |
+ TRACE_EVENT_FLOW_BEGIN0(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), |
+ queue_function, |
+ TRACE_ID_MANGLE(GetTaskTraceID(pending_task))); |
+} |
+ |
+void TaskAnnotator::RunTask(const char* queue_function, |
+ const char* run_function, |
+ const PendingTask& pending_task) { |
+ tracked_objects::TrackedTime start_time = |
+ tracked_objects::ThreadData::NowForStartOfRun(pending_task.birth_tally); |
+ tracked_objects::Duration queue_duration = |
+ start_time - pending_task.EffectiveTimePosted(); |
+ |
+ TRACE_EVENT_FLOW_END1(TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), |
+ queue_function, |
+ TRACE_ID_MANGLE(GetTaskTraceID(pending_task)), |
+ "queue_duration", |
+ queue_duration.InMilliseconds()); |
+ |
+ // When tracing memory for posted tasks it's more valuable to attribute the |
+ // memory allocations to the source function than generically to the task |
+ // runner. |
+ TRACE_EVENT_WITH_MEMORY_TAG2( |
+ "toplevel", |
+ run_function, |
+ pending_task.posted_from.function_name(), // Name for memory tracking. |
+ "src_file", |
+ pending_task.posted_from.file_name(), |
+ "src_func", |
+ pending_task.posted_from.function_name()); |
+ |
+ // Before running the task, store the program counter where it was posted |
+ // and deliberately alias it to ensure it is on the stack if the task |
+ // crashes. Be careful not to assume that the variable itself will have the |
+ // expected value when displayed by the optimizer in an optimized build. |
+ // Look at a memory dump of the stack. |
+ const void* program_counter = pending_task.posted_from.program_counter(); |
+ debug::Alias(&program_counter); |
+ |
+ pending_task.task.Run(); |
+ |
+ tracked_objects::ThreadData::TallyRunOnNamedThreadIfTracking( |
+ pending_task, start_time, tracked_objects::ThreadData::NowForEndOfRun()); |
+} |
+ |
+uint64 TaskAnnotator::GetTaskTraceID(const PendingTask& task) const { |
+ return (static_cast<uint64>(task.sequence_num) << 32) | |
+ ((static_cast<uint64>(reinterpret_cast<intptr_t>(this)) << 32) >> 32); |
+} |
+ |
+} // namespace debug |
+} // namespace base |