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

Unified Diff: base/tracked_objects.h

Issue 8233037: Update task tracking to not depend on message_loop_ singleton (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: base/tracked_objects.h
===================================================================
--- base/tracked_objects.h (revision 104925)
+++ base/tracked_objects.h (working copy)
@@ -65,7 +65,10 @@
// addition, the birth time is also recorded and used to later evaluate the
// lifetime duration of the whole Task. As a result of the above embedding, we
// can find out a Task's location of birth, and thread of birth, without using
-// any locks, as all that data is constant across the life of the process.
+// any locks, as all that data is constant across the life of the process. We
+// currently over-write the birth time with the time at which a Run() of the
+// task begins, so that we can calculate execution time independendent of
+// queueuing time (time spent in delayed task queues, or regular queues).
//
// This can also be done for any other object as well by calling
// TallyABirthIfActive() and TallyADeathIfActive() as appropriate.
@@ -81,7 +84,7 @@
// carefully accumulated. That tallying wrties into slots (members) in a
// collection of DeathData instances. For each birth place Location that is
// destroyed on a thread, there is a DeathData instance to record the additional
-// death count, as well as accumulate the lifetime duration of the instance as
+// death count, as well as accumulate the Run()time duration of the instance as
// it is destroyed (dies). By maintaining a single place to aggregate this
// addition *only* for the given thread, we avoid the need to lock such
// DeathData instances.
@@ -213,19 +216,20 @@
class BASE_EXPORT DeathData {
public:
// Default initializer.
- DeathData() : count_(0), square_duration_(0) {}
+ DeathData() : count_(0) {}
// When deaths have not yet taken place, and we gather data from all the
// threads, we create DeathData stats that tally the number of births without
// a corrosponding death.
- explicit DeathData(int count) : count_(count), square_duration_(0) {}
+ explicit DeathData(int count) : count_(count) {}
+ // Update stats for a task destruction (death) that had a Run() time of
+ // |duration|.
void RecordDeath(const base::TimeDelta& duration);
// Metrics accessors.
int count() const { return count_; }
base::TimeDelta life_duration() const { return life_duration_; }
- int64 square_duration() const { return square_duration_; }
int AverageMsDuration() const;
double StandardDeviation() const;
@@ -239,9 +243,8 @@
void Clear();
private:
- int count_; // Number of destructions.
- base::TimeDelta life_duration_; // Sum of all lifetime durations.
- int64 square_duration_; // Sum of squares in milliseconds.
+ int count_; // Number of destructions.
+ base::TimeDelta life_duration_; // Sum of all Run()time durations.
};
//------------------------------------------------------------------------------
@@ -270,7 +273,6 @@
int count() const { return death_data_.count(); }
base::TimeDelta life_duration() const { return death_data_.life_duration(); }
- int64 square_duration() const { return death_data_.square_duration(); }
int AverageMsDuration() const { return death_data_.AverageMsDuration(); }
void Write(std::string* output) const;
@@ -472,7 +474,7 @@
typedef std::map<Location, Births*> BirthMap;
typedef std::map<const Births*, DeathData> DeathMap;
- ThreadData();
+ explicit ThreadData(const char* suggested_name);
~ThreadData();
// Using Thread Local Store, find the current instance for collecting data.
@@ -480,7 +482,7 @@
// this thread.
// If shutdown has already started, and we don't yet have an instance, then
// return null.
- static ThreadData* current();
+ static ThreadData* FactoryGet(const char* suggested_name);
// For a given (unescaped) about:tracking query, develop resulting HTML, and
// append to output.
@@ -496,22 +498,31 @@
Births* TallyABirth(const Location& location);
// Find a place to record a death on this thread.
- void TallyADeath(const Births& lifetimes, const base::TimeDelta& duration);
+ void TallyADeath(const Births& the_birth, const base::TimeDelta& duration);
// Helper methods to only tally if the current thread has tracking active.
//
// TallyABirthIfActive will returns NULL if the birth cannot be tallied.
static Births* TallyABirthIfActive(const Location& location);
- static void TallyADeathIfActive(const Births* lifetimes,
- const base::TimeDelta& duration);
+ // Record the end of a timed run of an object. The |the_birth| is the record
+ // for the instance, the |time_posted| and |start_of_run| are times of posting
+ // into a message loop queue, and of starting to perform the run of the task.
+ // Implied is that the run just (Now()) ended. The current_message_loop is
+ // optional, and only used in DEBUG mode (when supplied) to verify that the
+ // ThreadData has a thread name that does indeed match the given loop's
+ // associated thread name (in RELEASE mode, its use is compiled away).
+ static void TallyADeathIfActive(const Births* the_birth,
+ const base::TimeTicks& time_posted,
+ const base::TimeTicks& start_of_run,
+ const MessageLoop* current_message_loop);
+
// (Thread safe) Get start of list of instances.
static ThreadData* first();
// Iterate through the null terminated list of instances.
ThreadData* next() const { return next_; }
- MessageLoop* message_loop() const { return message_loop_; }
- const std::string ThreadName() const;
+ const std::string thread_name() const { return thread_name_; }
// Using our lock, make a copy of the specified maps. These calls may arrive
// from non-local threads, and are used to quickly scan data from all threads
@@ -540,19 +551,11 @@
static bool StartTracking(bool status);
static bool IsActive();
-#ifdef OS_WIN
- // WARNING: ONLY call this function when all MessageLoops are still intact for
- // all registered threads. IF you call it later, you will crash.
- // Note: You don't need to call it at all, and you can wait till you are
- // single threaded (again) to do the cleanup via
- // ShutdownSingleThreadedCleanup().
- // Start the teardown (shutdown) process in a multi-thread mode by disabling
- // further additions to thread database on all threads. First it makes a
- // local (locked) change to prevent any more threads from registering. Then
- // it Posts a Task to all registered threads to be sure they are aware that no
- // more accumulation can take place.
- static void ShutdownMultiThreadTracking();
-#endif
+ // Provide a time function that does nothing (runs fast) when we don't have
+ // the profiler enabled. It will generally be optimized away when it is
+ // ifdef'ed to be small enough (allowing the profiler to be "compiled out" of
+ // the code).
+ static base::TimeTicks Now();
// WARNING: ONLY call this function when you are running single threaded
// (again) and all message loops and threads have terminated. Until that
@@ -570,11 +573,6 @@
SHUTDOWN,
};
-#if defined(OS_WIN)
- class ThreadSafeDownCounter;
- class RunTheStatic;
-#endif
-
// Each registered thread is called to set status_ to SHUTDOWN.
// This is done redundantly on every registered thread because it is not
// protected by a mutex. Running on all threads guarantees we get the
@@ -600,11 +598,15 @@
// data).
ThreadData* next_;
- // The message loop where tasks needing to access this instance's private data
- // should be directed. Since some threads have no message loop, some
- // instances have data that can't be (safely) modified externally.
- MessageLoop* message_loop_;
+ // The name of the thread that is being recorded. If this is a worker thread,
+ // or has no message_loop, then this string is empty.
+ std::string thread_name_;
+ // A sequential number indicating when this thread context was created. If
+ // the thread_name_ is empty, then this values will be used to form a unique
+ // name.
+ int thread_number_;
+
// A map used on each thread to keep track of Births on this thread.
// This map should only be accessed on the thread it was constructed on.
// When a snapshot is needed, this structure can be locked in place for the
@@ -625,6 +627,10 @@
// writing is only done from this thread.
mutable base::Lock lock_;
+ // The next available thread number. This should only be accessed when the
+ // list_lock_ is held.
+ static int thread_number_counter;
+
DISALLOW_COPY_AND_ASSIGN(ThreadData);
};

Powered by Google App Engine
This is Rietveld 408576698