Coverage Report

Created: 2018-09-25 14:53

/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