| 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);
|
| };
|
|
|
|
|