1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_PerformanceCounter_h
8 #define mozilla_PerformanceCounter_h
10 #include "mozilla/Array.h"
11 #include "mozilla/Atomics.h"
12 #include "mozilla/TaskCategory.h"
13 #include "nsISupportsImpl.h"
19 * The DispatchCategory class is used to fake the inheritance
20 * of the TaskCategory enum so we can extend it to hold
21 * one more value corresponding to the category
22 * we use when a worker dispatches a call.
25 class DispatchCategory final
{
27 explicit DispatchCategory(uint32_t aValue
) : mValue(aValue
) {
28 // Since DispatchCategory is adding one single value to the
29 // TaskCategory enum, we can check here that the value is
30 // the next index e.g. TaskCategory::Count
31 MOZ_ASSERT(aValue
== (uint32_t)TaskCategory::Count
);
34 constexpr explicit DispatchCategory(TaskCategory aValue
)
35 : mValue((uint32_t)aValue
) {}
37 uint32_t GetValue() const { return mValue
; }
39 static const DispatchCategory Worker
;
45 typedef Array
<Atomic
<uint32_t>, (uint32_t)TaskCategory::Count
+ 1>
48 // PerformanceCounter is a class that can be used to keep track of
49 // runnable execution times and dispatch counts.
51 // - runnable execution time: time spent in a runnable when called
52 // in nsThread::ProcessNextEvent (not counting recursive calls)
53 // - dispatch counts: number of times a tracked runnable is dispatched
54 // in nsThread. Useful to measure the activity of a tab or worker.
56 // The PerformanceCounter class is currently instantiated in DocGroup
57 // and WorkerPrivate in order to count how many scheduler dispatches
58 // are done through them, and how long the execution lasts.
60 // The execution time is calculated by the nsThread class (and its
61 // inherited WorkerThread class) in its ProcessNextEvent method.
63 // For each processed runnable, nsThread will reach out the
64 // PerformanceCounter attached to the runnable via its DocGroup
65 // or WorkerPrivate and call IncrementExecutionDuration()
67 // Notice that the execution duration counting takes into account
68 // recursivity. If an event triggers a recursive call to
69 // nsThread::ProcessNextEVent, the counter will discard the time
70 // spent in sub events.
71 class PerformanceCounter final
{
73 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PerformanceCounter
)
75 explicit PerformanceCounter(const nsACString
& aName
);
78 * This is called everytime a runnable is dispatched.
80 * aCategory can be used to distinguish counts per TaskCategory
82 * Note that an overflow will simply reset the counter.
84 void IncrementDispatchCounter(DispatchCategory aCategory
);
87 * This is called via nsThread::ProcessNextEvent to measure runnable
90 * Note that an overflow will simply reset the counter.
92 void IncrementExecutionDuration(uint32_t aMicroseconds
);
95 * Returns a category/counter array of all dispatches.
97 const DispatchCounter
& GetDispatchCounter() const;
100 * Returns the total execution duration.
102 uint64_t GetExecutionDuration() const;
105 * Returns the number of dispatches per TaskCategory.
107 uint32_t GetDispatchCount(DispatchCategory aCategory
) const;
110 * Returns the total number of dispatches.
112 uint64_t GetTotalDispatchCount() const;
115 * Returns the unique id for the instance.
117 * Used to distinguish instances since the lifespan of
118 * a PerformanceCounter can be shorter than the
119 * host it's tracking. That leads to edge cases
120 * where a counter appears to have values that go
121 * backwards. Having this id let the consumers
122 * detect that they are dealing with a new counter
125 uint64_t GetID() const;
128 ~PerformanceCounter() = default;
130 Atomic
<uint64_t> mExecutionDuration
;
131 Atomic
<uint64_t> mTotalDispatchCount
;
132 DispatchCounter mDispatchCounter
;
137 } // namespace mozilla
139 #endif // mozilla_PerformanceCounter_h