/work/obj-fuzz/dist/include/mozilla/PerformanceCounter.h
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #ifndef mozilla_PerformanceCounter_h |
8 | | #define mozilla_PerformanceCounter_h |
9 | | |
10 | | namespace mozilla { |
11 | | |
12 | | |
13 | | /* |
14 | | * The DispatchCategory class is used to fake the inheritance |
15 | | * of the TaskCategory enum so we can extend it to hold |
16 | | * one more value corresponding to the category |
17 | | * we use when a worker dispatches a call. |
18 | | * |
19 | | */ |
20 | | class DispatchCategory final |
21 | | { |
22 | | public: |
23 | | explicit DispatchCategory(uint32_t aValue) |
24 | | : mValue(aValue) |
25 | 3 | { |
26 | 3 | // Since DispatchCategory is adding one single value to the |
27 | 3 | // TaskCategory enum, we can check here that the value is |
28 | 3 | // the next index e.g. TaskCategory::Count |
29 | 3 | MOZ_ASSERT(aValue == (uint32_t)TaskCategory::Count); |
30 | 3 | } |
31 | | |
32 | | constexpr explicit DispatchCategory(TaskCategory aValue) |
33 | | : mValue((uint32_t)aValue) |
34 | 0 | {} |
35 | | |
36 | | uint32_t |
37 | | GetValue() const |
38 | 0 | { |
39 | 0 | return mValue; |
40 | 0 | } |
41 | | |
42 | | static const DispatchCategory Worker; |
43 | | private: |
44 | | uint32_t mValue; |
45 | | }; |
46 | | |
47 | | typedef Array<Atomic<uint32_t>, (uint32_t)TaskCategory::Count + 1> DispatchCounter; |
48 | | |
49 | | // PerformanceCounter is a class that can be used to keep track of |
50 | | // runnable execution times and dispatch counts. |
51 | | // |
52 | | // - runnable execution time: time spent in a runnable when called |
53 | | // in nsThread::ProcessNextEvent (not counting recursive calls) |
54 | | // - dispatch counts: number of times a tracked runnable is dispatched |
55 | | // in nsThread. Useful to measure the activity of a tab or worker. |
56 | | // |
57 | | // The PerformanceCounter class is currently instantiated in DocGroup |
58 | | // and WorkerPrivate in order to count how many scheduler dispatches |
59 | | // are done through them, and how long the execution lasts. |
60 | | // |
61 | | // The execution time is calculated by the nsThread class (and its |
62 | | // inherited WorkerThread class) in its ProcessNextEvent method. |
63 | | // |
64 | | // For each processed runnable, nsThread will reach out the |
65 | | // PerformanceCounter attached to the runnable via its DocGroup |
66 | | // or WorkerPrivate and call IncrementExecutionDuration() |
67 | | // |
68 | | // Notice that the execution duration counting takes into account |
69 | | // recursivity. If an event triggers a recursive call to |
70 | | // nsThread::ProcessNextEVent, the counter will discard the time |
71 | | // spent in sub events. |
72 | | class PerformanceCounter final |
73 | | { |
74 | | public: |
75 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PerformanceCounter) |
76 | | |
77 | | explicit PerformanceCounter(const nsACString& aName); |
78 | | |
79 | | /** |
80 | | * This is called everytime a runnable is dispatched. |
81 | | * |
82 | | * aCategory can be used to distinguish counts per TaskCategory |
83 | | * |
84 | | * Note that an overflow will simply reset the counter. |
85 | | */ |
86 | | void IncrementDispatchCounter(DispatchCategory aCategory); |
87 | | |
88 | | /** |
89 | | * This is called via nsThread::ProcessNextEvent to measure runnable |
90 | | * execution duration. |
91 | | * |
92 | | * Note that an overflow will simply reset the counter. |
93 | | */ |
94 | | void IncrementExecutionDuration(uint32_t aMicroseconds); |
95 | | |
96 | | /** |
97 | | * Returns a category/counter array of all dispatches. |
98 | | */ |
99 | | const DispatchCounter& GetDispatchCounter(); |
100 | | |
101 | | /** |
102 | | * Returns the total execution duration. |
103 | | */ |
104 | | uint64_t GetExecutionDuration(); |
105 | | |
106 | | /** |
107 | | * Returns the number of dispatches per TaskCategory. |
108 | | */ |
109 | | uint32_t GetDispatchCount(DispatchCategory aCategory); |
110 | | |
111 | | /** |
112 | | * Returns the total number of dispatches. |
113 | | */ |
114 | | uint64_t GetTotalDispatchCount(); |
115 | | |
116 | | /** |
117 | | * Returns the unique id for the instance. |
118 | | * |
119 | | * Used to distinguish instances since the lifespan of |
120 | | * a PerformanceCounter can be shorter than the |
121 | | * host it's tracking. That leads to edge cases |
122 | | * where a counter appears to have values that go |
123 | | * backwards. Having this id let the consumers |
124 | | * detect that they are dealing with a new counter |
125 | | * when it happens. |
126 | | */ |
127 | | uint64_t GetID() const; |
128 | | |
129 | | private: |
130 | 0 | ~PerformanceCounter() {} |
131 | | |
132 | | Atomic<uint64_t> mExecutionDuration; |
133 | | Atomic<uint64_t> mTotalDispatchCount; |
134 | | DispatchCounter mDispatchCounter; |
135 | | nsCString mName; |
136 | | const uint64_t mID; |
137 | | }; |
138 | | |
139 | | } // namespace mozilla |
140 | | |
141 | | #endif // mozilla_PerformanceCounter_h |