Chromium Code Reviews| 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 |
|
awong
2011/10/14 23:29:02
over-write -> overwrite
jar (doing other things)
2011/10/15 15:11:33
Done.
|
| +// 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); |
|
awong
2011/10/14 23:29:02
I thought the general pattern for singleton-ish ge
jar (doing other things)
2011/10/15 15:11:33
Done.
On 2011/10/14 23:29:02, awong wrote:
|
| // 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); |
| }; |