Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: webrtc/base/event_tracer.cc

Issue 1457383002: Implement standalone event tracing in AppRTCDemo. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: revert test_main.cc, it shouldn't be on for all tests either way Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 #include "webrtc/base/event_tracer.h"
10 11
11 #include "webrtc/base/event_tracer.h" 12 #include <inttypes.h>
13
14 #include <vector>
15
16 #include "webrtc/base/checks.h"
17 #include "webrtc/base/criticalsection.h"
18 #include "webrtc/base/event.h"
19 #include "webrtc/base/logging.h"
20 #include "webrtc/base/timeutils.h"
21 #include "webrtc/base/trace_event.h"
22 #include "webrtc/base/platform_thread.h"
23 #include "webrtc/system_wrappers/include/thread_wrapper.h"
12 24
13 namespace webrtc { 25 namespace webrtc {
14 26
15 namespace { 27 namespace {
16 28
17 GetCategoryEnabledPtr g_get_category_enabled_ptr = 0; 29 GetCategoryEnabledPtr g_get_category_enabled_ptr = nullptr;
18 AddTraceEventPtr g_add_trace_event_ptr = 0; 30 AddTraceEventPtr g_add_trace_event_ptr = nullptr;
19 31
20 } // namespace 32 } // namespace
21 33
22 void SetupEventTracer(GetCategoryEnabledPtr get_category_enabled_ptr, 34 void SetupEventTracer(GetCategoryEnabledPtr get_category_enabled_ptr,
23 AddTraceEventPtr add_trace_event_ptr) { 35 AddTraceEventPtr add_trace_event_ptr) {
24 g_get_category_enabled_ptr = get_category_enabled_ptr; 36 g_get_category_enabled_ptr = get_category_enabled_ptr;
25 g_add_trace_event_ptr = add_trace_event_ptr; 37 g_add_trace_event_ptr = add_trace_event_ptr;
26 } 38 }
27 39
28 // static 40 // static
(...skipping 21 matching lines...) Expand all
50 name, 62 name,
51 id, 63 id,
52 num_args, 64 num_args,
53 arg_names, 65 arg_names,
54 arg_types, 66 arg_types,
55 arg_values, 67 arg_values,
56 flags); 68 flags);
57 } 69 }
58 } 70 }
59 71
72 namespace {
73
74 struct TraceEvent {
75 const char* name;
76 const unsigned char* category_enabled;
tommi 2015/11/20 13:49:54 uint8_t?
pbos-webrtc 2015/11/20 15:11:05 Consistent with AddTraceEvent functions.
77 char phase;
tommi 2015/11/20 13:49:54 what is phase used for? Is this code borrowed from
pbos-webrtc 2015/11/20 15:11:05 Done, by referring to webrtc/base/trace_event.h. W
78 uint64_t timestamp;
79 int pid;
80 rtc::PlatformThreadId tid;
81 };
82
83 const unsigned char* InternalGetCategoryEnabled(const char* name) {
84 return reinterpret_cast<const unsigned char*>(
85 strstr(name, TRACE_DISABLED_BY_DEFAULT("")) == name ? "" : name);
tommi 2015/11/20 13:49:54 I'm not groking what this actually does or is supp
pbos-webrtc 2015/11/20 15:11:05 Should be a prefix search, I was lazy and did strs
86 }
87
88 static volatile int g_event_logging_active = 0;
89 static rtc::CriticalSection* g_event_crit;
tommi 2015/11/20 13:49:54 also initialize? can we bundle these variables in
pbos-webrtc 2015/11/20 15:11:05 class done
90 static std::vector<TraceEvent>* g_event_trace_events GUARDED_BY(g_event_crit) =
91 nullptr;
92
93 // Logging thread "members".
94 static ThreadWrapper* g_event_logging_thread = nullptr;
95 static rtc::Event* g_event_wakeup_event = nullptr;
96 static FILE* g_event_output_file = nullptr;
97 static bool g_event_output_file_owned;
tommi 2015/11/20 13:49:54 and this one?
pbos-webrtc 2015/11/20 15:11:05 Done.
98
99 void InternalAddTraceEvent(char phase,
100 const unsigned char* category_enabled,
101 const char* name,
102 unsigned long long id,
103 int num_args,
104 const char** arg_names,
105 const unsigned char* arg_types,
106 const unsigned long long* arg_values,
107 unsigned char flags) {
108 // Fast path for when event tracing is inactive.
109 if (rtc::AtomicOps::AcquireLoad(&g_event_logging_active) == 0)
110 return;
111
112 uint64_t timestamp = rtc::TimeMicros();
113 rtc::PlatformThreadId tid = rtc::CurrentThreadId();
114 rtc::CritScope lock(g_event_crit);
115 if (g_event_trace_events == nullptr)
116 return;
117 g_event_trace_events->push_back(
118 TraceEvent{name, category_enabled, phase, timestamp, 1, tid});
119 }
120
121 // TODO(pbos): Log metadata for all threads, etc.
122 bool LoggingThread(void* obj) {
123 static const int kLoggingIntervalMs = 100;
124 fprintf(g_event_output_file, "{ \"traceEvents\": [\n");
125 bool has_logged_event = false;
126 while (true) {
127 g_event_wakeup_event->Wait(kLoggingIntervalMs);
128 std::vector<TraceEvent> events;
129 {
130 rtc::CritScope lock(g_event_crit);
131 g_event_trace_events->swap(events);
132 }
133 for (const TraceEvent e : events) {
tommi 2015/11/20 13:49:54 copy by value intentionally or missing &?
pbos-webrtc 2015/11/20 15:11:05 Done.
134 fprintf(g_event_output_file,
135 "%s{ \"name\": \"%s\""
136 ", \"cat\": \"%s\""
137 ", \"ph\": \"%c\""
138 ", \"ts\": %" PRIu64
139 ", \"pid\": %d"
140 ", \"tid\": %d}\n",
141 has_logged_event ? "," : " ", e.name, e.category_enabled, e.phase,
142 e.timestamp, e.pid, e.tid);
143 has_logged_event = true;
144 }
145 if (rtc::AtomicOps::AcquireLoad(&g_event_logging_active) == 0)
146 break;
147 }
148 fprintf(g_event_output_file, "]}\n");
149 if (g_event_output_file_owned)
150 fclose(g_event_output_file);
151 {
152 rtc::CritScope lock(g_event_crit);
153 delete g_event_trace_events;
154 g_event_trace_events = nullptr;
155 }
156 // We're done, so return false to prevent another run w/ wait.
157 return false;
158 }
159
160 void StartInternalCaptureToFilePtr(FILE* output_file,
161 bool file_owned_by_tracer) {
162 RTC_DCHECK(!g_event_crit) << "Internal tracing not initialized.";
163 RTC_DCHECK(!g_event_logging_thread)
164 << "Internal tracing should not start twice.";
165 RTC_DCHECK_EQ(0, rtc::AtomicOps::AcquireLoad(&g_event_logging_active));
166 g_event_output_file = output_file;
tommi 2015/11/20 13:49:54 how do we know we're not overwriting a previous va
pbos-webrtc 2015/11/20 15:11:05 Assuming that start and stop are done on the same
167 g_event_output_file_owned = file_owned_by_tracer;
168 {
169 rtc::CritScope lock(g_event_crit);
170 g_event_trace_events = new std::vector<TraceEvent>();
171 }
172 g_event_wakeup_event = new rtc::Event(false, false);
173 g_event_logging_thread =
174 ThreadWrapper::CreateThread(&LoggingThread, nullptr, "EventTracingThread")
tommi 2015/11/20 13:49:54 instead of having g_event_output_file be a global,
pbos-webrtc 2015/11/20 15:11:05 -> class
175 .release();
176 rtc::AtomicOps::ReleaseStore(&g_event_logging_active, 1);
177
178 // Finally start, everything should be set up now.
179 g_event_logging_thread->Start();
180 }
181
182 } // namespace
183
184 // static
185 void EventTracer::SetupInternalTracer() {
186 RTC_DCHECK(!g_get_category_enabled_ptr);
187 RTC_DCHECK(!g_add_trace_event_ptr);
188 g_event_crit = new rtc::CriticalSection();
189 SetupEventTracer(InternalGetCategoryEnabled, InternalAddTraceEvent);
190 }
191
192 void EventTracer::StartInternalCaptureToFile(FILE* file) {
193 StartInternalCaptureToFilePtr(file, false);
194 }
195
196 bool EventTracer::StartInternalCapture(const char* filename) {
197 FILE* file = fopen(filename, "w");
198 if (!file) {
199 LOG(LS_ERROR) << "Failed to open trace file '" << filename
200 << "' for writing.";
201 return false;
202 }
203 StartInternalCaptureToFilePtr(file, true);
204 return true;
205 }
206
207 void EventTracer::StopInternalCapture() {
208 // Abort if we're not currently logging.
209 if (rtc::AtomicOps::AcquireLoad(&g_event_logging_active) == 0)
tommi 2015/11/20 13:49:54 this should also be a CompareAndSwap since otherwi
pbos-webrtc 2015/11/20 15:11:05 This is only a best-effort fast path for early abo
210 return;
211 // Disable event logging.
212 rtc::AtomicOps::ReleaseStore(&g_event_logging_active, 0);
213 // Wake up logging thread to finish writing.
214 g_event_wakeup_event->Set();
215 // Join the logging thread.
216 g_event_logging_thread->Stop();
217 delete g_event_logging_thread;
218 delete g_event_wakeup_event;
219 g_event_logging_thread = nullptr;
220 g_event_wakeup_event = nullptr;
221 }
222
223 void EventTracer::ShutdownInternalTracer() {
224 StopInternalCapture();
225 RTC_DCHECK(g_get_category_enabled_ptr == InternalGetCategoryEnabled);
226 RTC_DCHECK(g_add_trace_event_ptr == InternalAddTraceEvent);
227 SetupEventTracer(nullptr, nullptr);
228 delete g_event_crit;
229 g_event_crit = nullptr;
230 }
231
60 } // namespace webrtc 232 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698