blob: 13b99f7c91f6cd36ae1ea508fe85246217a1dd46 [file] [log] [blame]
henrike@webrtc.orgf7795df2014-05-13 18:00:26 +00001/*
2 * Copyright 2013 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11// A simple wall-clock profiler for instrumented code.
12// Example:
13// void MyLongFunction() {
14// PROFILE_F(); // Time the execution of this function.
15// // Do something
16// { // Time just what is in this scope.
17// PROFILE("My event");
18// // Do something else
19// }
20// }
21// Another example:
22// void StartAsyncProcess() {
23// PROFILE_START("My async event");
24// DoSomethingAsyncAndThenCall(&Callback);
25// }
26// void Callback() {
27// PROFILE_STOP("My async event");
28// // Handle callback.
29// }
30
31#ifndef WEBRTC_BASE_PROFILER_H_
32#define WEBRTC_BASE_PROFILER_H_
33
34#include <map>
35#include <string>
36
37#include "webrtc/base/basictypes.h"
38#include "webrtc/base/common.h"
39#include "webrtc/base/logging.h"
40#include "webrtc/base/sharedexclusivelock.h"
41
42// Profiling could be switched via a build flag, but for now, it's always on.
43#ifndef ENABLE_PROFILING
44#define ENABLE_PROFILING
45#endif
46
47#ifdef ENABLE_PROFILING
48
49#define UV_HELPER2(x) _uv_ ## x
50#define UV_HELPER(x) UV_HELPER2(x)
51#define UNIQUE_VAR UV_HELPER(__LINE__)
52
53// Profiles the current scope.
54#define PROFILE(msg) rtc::ProfilerScope UNIQUE_VAR(msg)
55// When placed at the start of a function, profiles the current function.
56#define PROFILE_F() PROFILE(__FUNCTION__)
57// Reports current timings to the log at severity |sev|.
58#define PROFILE_DUMP_ALL(sev) \
59 rtc::Profiler::Instance()->ReportAllToLog(__FILE__, __LINE__, sev)
60// Reports current timings for all events whose names are prefixed by |prefix|
61// to the log at severity |sev|. Using a unique event name as |prefix| will
62// report only that event.
63#define PROFILE_DUMP(sev, prefix) \
64 rtc::Profiler::Instance()->ReportToLog(__FILE__, __LINE__, sev, prefix)
65// Starts and stops a profile event. Useful when an event is not easily
66// captured within a scope (eg, an async call with a callback when done).
67#define PROFILE_START(msg) rtc::Profiler::Instance()->StartEvent(msg)
68#define PROFILE_STOP(msg) rtc::Profiler::Instance()->StopEvent(msg)
69// TODO(ryanpetrie): Consider adding PROFILE_DUMP_EVERY(sev, iterations)
70
71#undef UV_HELPER2
72#undef UV_HELPER
73#undef UNIQUE_VAR
74
75#else // ENABLE_PROFILING
76
77#define PROFILE(msg) (void)0
78#define PROFILE_F() (void)0
79#define PROFILE_DUMP_ALL(sev) (void)0
80#define PROFILE_DUMP(sev, prefix) (void)0
81#define PROFILE_START(msg) (void)0
82#define PROFILE_STOP(msg) (void)0
83
84#endif // ENABLE_PROFILING
85
86namespace rtc {
87
88// Tracks information for one profiler event.
89class ProfilerEvent {
90 public:
91 ProfilerEvent();
92 void Start();
93 void Stop();
94 void Stop(uint64 stop_time);
95 double standard_deviation() const;
96 double total_time() const { return total_time_; }
97 double mean() const { return mean_; }
98 double minimum() const { return minimum_; }
99 double maximum() const { return maximum_; }
100 int event_count() const { return event_count_; }
101 bool is_started() const { return start_count_ > 0; }
102
103 private:
104 uint64 current_start_time_;
105 double total_time_;
106 double mean_;
107 double sum_of_squared_differences_;
108 double minimum_;
109 double maximum_;
110 int start_count_;
111 int event_count_;
112};
113
114// Singleton that owns ProfilerEvents and reports results. Prefer to use
115// macros, defined above, rather than directly calling Profiler methods.
116class Profiler {
117 public:
118 void StartEvent(const std::string& event_name);
119 void StopEvent(const std::string& event_name);
120 void ReportToLog(const char* file, int line, LoggingSeverity severity_to_use,
121 const std::string& event_prefix);
122 void ReportAllToLog(const char* file, int line,
123 LoggingSeverity severity_to_use);
124 const ProfilerEvent* GetEvent(const std::string& event_name) const;
125 // Clears all _stopped_ events. Returns true if _all_ events were cleared.
126 bool Clear();
127
128 static Profiler* Instance();
129 private:
130 Profiler() {}
131
132 typedef std::map<std::string, ProfilerEvent> EventMap;
133 EventMap events_;
134 mutable SharedExclusiveLock lock_;
135
136 DISALLOW_COPY_AND_ASSIGN(Profiler);
137};
138
139// Starts an event on construction and stops it on destruction.
140// Used by PROFILE macro.
141class ProfilerScope {
142 public:
143 explicit ProfilerScope(const std::string& event_name)
144 : event_name_(event_name) {
145 Profiler::Instance()->StartEvent(event_name_);
146 }
147 ~ProfilerScope() {
148 Profiler::Instance()->StopEvent(event_name_);
149 }
150 private:
151 std::string event_name_;
152
153 DISALLOW_COPY_AND_ASSIGN(ProfilerScope);
154};
155
156std::ostream& operator<<(std::ostream& stream,
157 const ProfilerEvent& profiler_event);
158
159} // namespace rtc
160
161#endif // WEBRTC_BASE_PROFILER_H_