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

Side by Side Diff: base/debug/trace_event_impl.h

Issue 10837082: implement SetWatchEvent and WaitForEvent for trace-based-tests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleaned up and fixed a bug Created 8 years, 4 months 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | base/debug/trace_event_impl.cc » ('j') | base/debug/trace_event_impl.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 5
6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_ 6 #ifndef BASE_DEBUG_TRACE_EVENT_IMPL_H_
7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_ 7 #define BASE_DEBUG_TRACE_EVENT_IMPL_H_
8 8
9 #include "build/build_config.h" 9 #include "build/build_config.h"
10 10
11 #include <string> 11 #include <string>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/callback.h" 14 #include "base/callback.h"
15 #include "base/hash_tables.h" 15 #include "base/hash_tables.h"
16 #include "base/memory/ref_counted_memory.h" 16 #include "base/memory/ref_counted_memory.h"
17 #include "base/observer_list.h" 17 #include "base/observer_list.h"
18 #include "base/string_util.h" 18 #include "base/string_util.h"
19 #include "base/synchronization/condition_variable.h"
19 #include "base/synchronization/lock.h" 20 #include "base/synchronization/lock.h"
20 #include "base/timer.h" 21 #include "base/timer.h"
21 22
22 // Older style trace macros with explicit id and extra data 23 // Older style trace macros with explicit id and extra data
23 // Only these macros result in publishing data to ETW as currently implemented. 24 // Only these macros result in publishing data to ETW as currently implemented.
24 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ 25 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \
25 base::debug::TraceLog::AddTraceEventEtw( \ 26 base::debug::TraceLog::AddTraceEventEtw( \
26 TRACE_EVENT_PHASE_BEGIN, \ 27 TRACE_EVENT_PHASE_BEGIN, \
27 name, reinterpret_cast<const void*>(id), extra) 28 name, reinterpret_cast<const void*>(id), extra)
28 29
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 void AppendAsJSON(std::string* out) const; 83 void AppendAsJSON(std::string* out) const;
83 84
84 TimeTicks timestamp() const { return timestamp_; } 85 TimeTicks timestamp() const { return timestamp_; }
85 86
86 // Exposed for unittesting: 87 // Exposed for unittesting:
87 88
88 const base::RefCountedString* parameter_copy_storage() const { 89 const base::RefCountedString* parameter_copy_storage() const {
89 return parameter_copy_storage_.get(); 90 return parameter_copy_storage_.get();
90 } 91 }
91 92
93 const unsigned char* category_enabled() const { return category_enabled_; }
92 const char* name() const { return name_; } 94 const char* name() const { return name_; }
93 95
94 private: 96 private:
95 // Note: these are ordered by size (largest first) for optimal packing. 97 // Note: these are ordered by size (largest first) for optimal packing.
96 TimeTicks timestamp_; 98 TimeTicks timestamp_;
97 // id_ can be used to store phase-specific data. 99 // id_ can be used to store phase-specific data.
98 unsigned long long id_; 100 unsigned long long id_;
99 TraceValue arg_values_[kTraceMaxNumArgs]; 101 TraceValue arg_values_[kTraceMaxNumArgs];
100 const char* arg_names_[kTraceMaxNumArgs]; 102 const char* arg_names_[kTraceMaxNumArgs];
101 const unsigned char* category_enabled_; 103 const unsigned char* category_enabled_;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 void Finish(); 149 void Finish();
148 150
149 private: 151 private:
150 OutputCallback output_callback_; 152 OutputCallback output_callback_;
151 bool append_comma_; 153 bool append_comma_;
152 }; 154 };
153 155
154 156
155 class BASE_EXPORT TraceLog { 157 class BASE_EXPORT TraceLog {
156 public: 158 public:
159 // Notification is a mask of one or more of the following events.
160 enum Notification {
ccameron 2012/08/21 01:06:34 This isn't treated as a bit mask (but rather as a
jbates 2012/08/23 22:45:28 Good catch, TraceControllerImpl::OnTraceNotificati
161 // The trace buffer does not flush dynamically, so when it fills up,
162 // subsequent trace events will be dropped. This callback is generated when
163 // the trace buffer is full. The callback must be thread safe.
164 TRACE_BUFFER_FULL = 1 << 0,
165 // A subscribed trace-event occurred.
166 EVENT_WATCH_NOTIFICATION = 1 << 1
167 };
168
157 static TraceLog* GetInstance(); 169 static TraceLog* GetInstance();
158 170
159 // Get set of known categories. This can change as new code paths are reached. 171 // Get set of known categories. This can change as new code paths are reached.
160 // The known categories are inserted into |categories|. 172 // The known categories are inserted into |categories|.
161 void GetKnownCategories(std::vector<std::string>* categories); 173 void GetKnownCategories(std::vector<std::string>* categories);
162 174
163 // Enable tracing for provided list of categories. If tracing is already 175 // Enable tracing for provided list of categories. If tracing is already
164 // enabled, this method does nothing -- changing categories during trace is 176 // enabled, this method does nothing -- changing categories during trace is
165 // not supported. 177 // not supported.
166 // If both included_categories and excluded_categories are empty, 178 // If both included_categories and excluded_categories are empty,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 // still false at this point TRACE macros will still be capturing 218 // still false at this point TRACE macros will still be capturing
207 // data. However, trace macros and methods called within the observer will 219 // data. However, trace macros and methods called within the observer will
208 // deadlock. 220 // deadlock.
209 virtual void OnTraceLogWillDisable() { } 221 virtual void OnTraceLogWillDisable() { }
210 }; 222 };
211 void AddEnabledStateObserver(EnabledStateChangedObserver* listener); 223 void AddEnabledStateObserver(EnabledStateChangedObserver* listener);
212 void RemoveEnabledStateObserver(EnabledStateChangedObserver* listener); 224 void RemoveEnabledStateObserver(EnabledStateChangedObserver* listener);
213 225
214 float GetBufferPercentFull() const; 226 float GetBufferPercentFull() const;
215 227
216 // When enough events are collected, they are handed (in bulk) to 228 // Set the thread-safe notification callback. The callback can occur at any
217 // the output callback. If no callback is set, the output will be 229 // time. After calling SetNotificationCallback(NotificationCallback()) to
218 // silently dropped. The callback must be thread safe. The string format is 230 // clear the callback, it is guaranteed that the old callback will no longer
231 // be called. Warning: it is possible for the old callback to be called during
232 // a call to SetNotificationCallback.
233 typedef base::Callback<void(int)> NotificationCallback;
234 void SetNotificationCallback(const NotificationCallback& cb);
235
236 // Flush all collected events to the given output callback. The callback will
237 // be called one or more times with IPC-bite-size chunks. The string format is
219 // undefined. Use TraceResultBuffer to convert one or more trace strings to 238 // undefined. Use TraceResultBuffer to convert one or more trace strings to
220 // JSON. 239 // JSON.
221 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)> 240 typedef base::Callback<void(const scoped_refptr<base::RefCountedString>&)>
222 OutputCallback; 241 OutputCallback;
223 void SetOutputCallback(const OutputCallback& cb); 242 void Flush(const OutputCallback& cb);
224
225 // The trace buffer does not flush dynamically, so when it fills up,
226 // subsequent trace events will be dropped. This callback is generated when
227 // the trace buffer is full. The callback must be thread safe.
228 typedef base::Callback<void(void)> BufferFullCallback;
229 void SetBufferFullCallback(const BufferFullCallback& cb);
230
231 // Flushes all logged data to the callback.
232 void Flush();
233 243
234 // Called by TRACE_EVENT* macros, don't call this directly. 244 // Called by TRACE_EVENT* macros, don't call this directly.
235 static const unsigned char* GetCategoryEnabled(const char* name); 245 static const unsigned char* GetCategoryEnabled(const char* name);
236 static const char* GetCategoryName(const unsigned char* category_enabled); 246 static const char* GetCategoryName(const unsigned char* category_enabled);
237 247
238 // Called by TRACE_EVENT* macros, don't call this directly. 248 // Called by TRACE_EVENT* macros, don't call this directly.
239 // Returns the index in the internal vector of the event if it was added, or 249 // Returns the index in the internal vector of the event if it was added, or
240 // -1 if the event was not added. 250 // -1 if the event was not added.
241 // On end events, the return value of the begin event can be specified along 251 // On end events, the return value of the begin event can be specified along
242 // with a threshold in microseconds. If the elapsed time between begin and end 252 // with a threshold in microseconds. If the elapsed time between begin and end
(...skipping 13 matching lines...) Expand all
256 unsigned char flags); 266 unsigned char flags);
257 static void AddTraceEventEtw(char phase, 267 static void AddTraceEventEtw(char phase,
258 const char* name, 268 const char* name,
259 const void* id, 269 const void* id,
260 const char* extra); 270 const char* extra);
261 static void AddTraceEventEtw(char phase, 271 static void AddTraceEventEtw(char phase,
262 const char* name, 272 const char* name,
263 const void* id, 273 const void* id,
264 const std::string& extra); 274 const std::string& extra);
265 275
276 // After |num_occurrences| of given event have been seen on a particular
277 // process since tracing was enabled, a notification will be fired. The event
278 // count is not distributed across processes, so |num_occurrences| must occur
279 // on one process. The watch event is automatically cleared after the
280 // notification. |num_occurrences| must be greater than 0.
281 // NOTE: If |num_occurrences| events have already occurred, the notification
ccameron 2012/08/21 01:06:34 I have a preference for not supporting this semant
jbates 2012/08/23 22:45:28 This is important to catch the events that occur a
282 // will fire during the call to SetWatchEvent.
283 void SetWatchEvent(const char* category_name,
284 const char* event_name,
285 int num_occurrences);
286 // Cancel the watch event. If tracing is enabled, this may race with the
287 // watch event notification firing.
288 void CancelWatchEvent();
289
266 int process_id() const { return process_id_; } 290 int process_id() const { return process_id_; }
267 291
268 // Exposed for unittesting: 292 // Exposed for unittesting:
269 293
270 // Allows deleting our singleton instance. 294 // Allows deleting our singleton instance.
271 static void DeleteForTesting(); 295 static void DeleteForTesting();
272 296
273 // Allows resurrecting our singleton instance post-AtExit processing. 297 // Allows resurrecting our singleton instance post-AtExit processing.
274 static void Resurrect(); 298 static void Resurrect();
275 299
276 // Allow tests to inspect TraceEvents. 300 // Allow tests to inspect TraceEvents.
277 size_t GetEventsSize() const { return logged_events_.size(); } 301 size_t GetEventsSize() const { return logged_events_.size(); }
278 const TraceEvent& GetEventAt(size_t index) const { 302 const TraceEvent& GetEventAt(size_t index) const {
279 DCHECK(index < logged_events_.size()); 303 DCHECK(index < logged_events_.size());
280 return logged_events_[index]; 304 return logged_events_[index];
281 } 305 }
282 306
283 void SetProcessID(int process_id); 307 void SetProcessID(int process_id);
284 308
285 private: 309 private:
286 // This allows constructor and destructor to be private and usable only 310 // This allows constructor and destructor to be private and usable only
287 // by the Singleton class. 311 // by the Singleton class.
288 friend struct StaticMemorySingletonTraits<TraceLog>; 312 friend struct StaticMemorySingletonTraits<TraceLog>;
289 313
314 // Helper class for managing notification_thread_count_ and running
315 // notification callbacks.
316 class NotificationHelper {
317 public:
318 inline NotificationHelper(TraceLog* trace_log);
319 inline ~NotificationHelper();
320
321 // Called only while TraceLog::lock_ is held.
322 inline void AddNotificationWhileLocked(int notification);
323
324 // Called only while TraceLog::lock_ is NOT held.
325 inline void SendNotificationIfAny();
326
327 private:
328 TraceLog* trace_log_;
329 NotificationCallback callback_copy_;
330 int notification_;
331 };
332
290 TraceLog(); 333 TraceLog();
291 ~TraceLog(); 334 ~TraceLog();
292 const unsigned char* GetCategoryEnabledInternal(const char* name); 335 const unsigned char* GetCategoryEnabledInternal(const char* name);
293 void AddThreadNameMetadataEvents(); 336 void AddThreadNameMetadataEvents();
294 void AddClockSyncMetadataEvents(); 337 void AddClockSyncMetadataEvents();
295 338
296 // TODO(nduca): switch to per-thread trace buffers to reduce thread 339 // TODO(nduca): switch to per-thread trace buffers to reduce thread
297 // synchronization. 340 // synchronization.
298 Lock lock_; 341 Lock lock_;
299 bool enabled_; 342 bool enabled_;
300 OutputCallback output_callback_; 343 base::ConditionVariable notification_condition_;
301 BufferFullCallback buffer_full_callback_; 344 NotificationCallback notification_callback_;
ccameron 2012/08/21 01:06:34 I see no concurrency issues with this implementati
jbates 2012/08/23 22:45:28 As discussed, added comments around the Notificati
345 // Number of threads that are have a copy of the notification callback.
346 int notification_thread_count_;
302 std::vector<TraceEvent> logged_events_; 347 std::vector<TraceEvent> logged_events_;
303 std::vector<std::string> included_categories_; 348 std::vector<std::string> included_categories_;
304 std::vector<std::string> excluded_categories_; 349 std::vector<std::string> excluded_categories_;
305 bool dispatching_to_observer_list_; 350 bool dispatching_to_observer_list_;
306 ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_; 351 ObserverList<EnabledStateChangedObserver> enabled_state_observer_list_;
307 352
308 base::hash_map<int, std::string> thread_names_; 353 base::hash_map<int, std::string> thread_names_;
309 354
310 // XORed with TraceID to make it unlikely to collide with other processes. 355 // XORed with TraceID to make it unlikely to collide with other processes.
311 unsigned long long process_id_hash_; 356 unsigned long long process_id_hash_;
312 357
313 int process_id_; 358 int process_id_;
314 359
360 // Allow tests to wake up when certain events occur.
361 const unsigned char* watch_category_;
362 std::string watch_event_name_;
363 int watch_count_;
364
315 DISALLOW_COPY_AND_ASSIGN(TraceLog); 365 DISALLOW_COPY_AND_ASSIGN(TraceLog);
316 }; 366 };
317 367
318 } // namespace debug 368 } // namespace debug
319 } // namespace base 369 } // namespace base
320 370
321 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_ 371 #endif // BASE_DEBUG_TRACE_EVENT_IMPL_H_
OLDNEW
« no previous file with comments | « no previous file | base/debug/trace_event_impl.cc » ('j') | base/debug/trace_event_impl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698