- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / base / profiler.h
1 /*
2  * libjingle
3  * Copyright 2013, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 // A simple wall-clock profiler for instrumented code.
29 // Example:
30 //   void MyLongFunction() {
31 //     PROFILE_F();  // Time the execution of this function.
32 //     // Do something
33 //     {  // Time just what is in this scope.
34 //       PROFILE("My event");
35 //       // Do something else
36 //     }
37 //   }
38 // Another example:
39 //   void StartAsyncProcess() {
40 //     PROFILE_START("My async event");
41 //     DoSomethingAsyncAndThenCall(&Callback);
42 //   }
43 //   void Callback() {
44 //     PROFILE_STOP("My async event");
45 //     // Handle callback.
46 //   }
47
48 #ifndef TALK_BASE_PROFILER_H_
49 #define TALK_BASE_PROFILER_H_
50
51 #include <map>
52 #include <string>
53
54 #include "talk/base/basictypes.h"
55 #include "talk/base/common.h"
56 #include "talk/base/logging.h"
57 #include "talk/base/sharedexclusivelock.h"
58
59 // Profiling could be switched via a build flag, but for now, it's always on.
60 #define ENABLE_PROFILING
61
62 #ifdef ENABLE_PROFILING
63
64 #define UV_HELPER2(x) _uv_ ## x
65 #define UV_HELPER(x) UV_HELPER2(x)
66 #define UNIQUE_VAR UV_HELPER(__LINE__)
67
68 // Profiles the current scope.
69 #define PROFILE(msg) talk_base::ProfilerScope UNIQUE_VAR(msg)
70 // When placed at the start of a function, profiles the current function.
71 #define PROFILE_F() PROFILE(__FUNCTION__)
72 // Reports current timings to the log at severity |sev|.
73 #define PROFILE_DUMP_ALL(sev) \
74   talk_base::Profiler::Instance()->ReportAllToLog(__FILE__, __LINE__, sev)
75 // Reports current timings for all events whose names are prefixed by |prefix|
76 // to the log at severity |sev|. Using a unique event name as |prefix| will
77 // report only that event.
78 #define PROFILE_DUMP(sev, prefix) \
79   talk_base::Profiler::Instance()->ReportToLog(__FILE__, __LINE__, sev, prefix)
80 // Starts and stops a profile event. Useful when an event is not easily
81 // captured within a scope (eg, an async call with a callback when done).
82 #define PROFILE_START(msg) talk_base::Profiler::Instance()->StartEvent(msg)
83 #define PROFILE_STOP(msg) talk_base::Profiler::Instance()->StopEvent(msg)
84 // TODO(ryanpetrie): Consider adding PROFILE_DUMP_EVERY(sev, iterations)
85
86 #undef UV_HELPER2
87 #undef UV_HELPER
88 #undef UNIQUE_VAR
89
90 #else  // ENABLE_PROFILING
91
92 #define PROFILE(msg) (void)0
93 #define PROFILE_F() (void)0
94 #define PROFILE_DUMP_ALL(sev) (void)0
95 #define PROFILE_DUMP(sev, prefix) (void)0
96 #define PROFILE_START(msg) (void)0
97 #define PROFILE_STOP(msg) (void)0
98
99 #endif  // ENABLE_PROFILING
100
101 namespace talk_base {
102
103 // Tracks information for one profiler event.
104 class ProfilerEvent {
105  public:
106   ProfilerEvent();
107   void Start();
108   void Stop();
109   void Stop(uint64 stop_time);
110   double standard_deviation() const;
111   double total_time() const { return total_time_; }
112   double mean() const { return mean_; }
113   double minimum() const { return minimum_; }
114   double maximum() const { return maximum_; }
115   int event_count() const { return event_count_; }
116   bool is_started() const { return start_count_ > 0; }
117
118  private:
119   uint64 current_start_time_;
120   double total_time_;
121   double mean_;
122   double sum_of_squared_differences_;
123   double minimum_;
124   double maximum_;
125   int start_count_;
126   int event_count_;
127 };
128
129 // Singleton that owns ProfilerEvents and reports results. Prefer to use
130 // macros, defined above, rather than directly calling Profiler methods.
131 class Profiler {
132  public:
133   void StartEvent(const std::string& event_name);
134   void StopEvent(const std::string& event_name);
135   void ReportToLog(const char* file, int line, LoggingSeverity severity_to_use,
136                    const std::string& event_prefix);
137   void ReportAllToLog(const char* file, int line,
138                       LoggingSeverity severity_to_use);
139   const ProfilerEvent* GetEvent(const std::string& event_name) const;
140   // Clears all _stopped_ events. Returns true if _all_ events were cleared.
141   bool Clear();
142
143   static Profiler* Instance();
144  private:
145   Profiler() {}
146
147   typedef std::map<std::string, ProfilerEvent> EventMap;
148   EventMap events_;
149   mutable SharedExclusiveLock lock_;
150
151   DISALLOW_COPY_AND_ASSIGN(Profiler);
152 };
153
154 // Starts an event on construction and stops it on destruction.
155 // Used by PROFILE macro.
156 class ProfilerScope {
157  public:
158   explicit ProfilerScope(const std::string& event_name)
159       : event_name_(event_name) {
160     Profiler::Instance()->StartEvent(event_name_);
161   }
162   ~ProfilerScope() {
163     Profiler::Instance()->StopEvent(event_name_);
164   }
165  private:
166   std::string event_name_;
167
168   DISALLOW_COPY_AND_ASSIGN(ProfilerScope);
169 };
170
171 std::ostream& operator<<(std::ostream& stream,
172                          const ProfilerEvent& profiler_event);
173
174 }  // namespace talk_base
175
176 #endif  // TALK_BASE_PROFILER_H_