1 // Copyright 2016 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TRACE_EVENT_AUTO_OPEN_CLOSE_EVENT_H_ 6 #define BASE_TRACE_EVENT_AUTO_OPEN_CLOSE_EVENT_H_ 7 8 #include "base/check.h" 9 #include "base/memory/weak_ptr.h" 10 #include "base/threading/thread_checker.h" 11 #include "base/time/time.h" 12 #include "base/trace_event/trace_event.h" 13 14 namespace base { 15 namespace trace_event { 16 17 // Class for tracing events that support "auto-opening" and "auto-closing". 18 // "auto-opening" = if the trace event is started (call Begin() before 19 // tracing is started,the trace event will be opened, with the start time 20 // being the time that the trace event was actually started. 21 // "auto-closing" = if the trace event is started but not ended by the time 22 // tracing ends, then the trace event will be automatically closed at the 23 // end of tracing. 24 // |category| must be known at compile-time in order to be used in trace macros. 25 // Hence, it's passed as a class templace argument. 26 template <const char* category> 27 class AutoOpenCloseEvent : public TraceLog::AsyncEnabledStateObserver { 28 public: 29 enum Type { 30 ASYNC 31 }; 32 33 // As in the rest of the tracing macros, the const char* arguments here 34 // must be pointers to indefinitely lived strings (e.g. hard-coded string 35 // literals are okay, but not strings created by c_str()) AutoOpenCloseEvent(Type type,const char * event_name)36 AutoOpenCloseEvent(Type type, const char* event_name) 37 : event_name_(event_name) { 38 base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver( 39 weak_factory_.GetWeakPtr()); 40 } 41 AutoOpenCloseEvent(const AutoOpenCloseEvent&) = delete; 42 AutoOpenCloseEvent& operator=(const AutoOpenCloseEvent&) = delete; ~AutoOpenCloseEvent()43 ~AutoOpenCloseEvent() override { 44 DCHECK(thread_checker_.CalledOnValidThread()); 45 base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver( 46 this); 47 } 48 Begin()49 void Begin() { 50 DCHECK(thread_checker_.CalledOnValidThread()); 51 start_time_ = TRACE_TIME_TICKS_NOW(); 52 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0( 53 category, event_name_, static_cast<void*>(this), start_time_); 54 } End()55 void End() { 56 DCHECK(thread_checker_.CalledOnValidThread()); 57 TRACE_EVENT_ASYNC_END0(category, event_name_, static_cast<void*>(this)); 58 start_time_ = base::TimeTicks(); 59 } 60 61 // AsyncEnabledStateObserver implementation OnTraceLogEnabled()62 void OnTraceLogEnabled() override { 63 DCHECK(thread_checker_.CalledOnValidThread()); 64 if (!start_time_.is_null()) { 65 TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0( 66 category, event_name_, static_cast<void*>(this), start_time_); 67 } 68 } OnTraceLogDisabled()69 void OnTraceLogDisabled() override {} 70 71 private: 72 const char* const event_name_; 73 base::TimeTicks start_time_; 74 base::ThreadChecker thread_checker_; 75 WeakPtrFactory<AutoOpenCloseEvent> weak_factory_{this}; 76 }; 77 78 } // namespace trace_event 79 } // namespace base 80 81 #endif // BASE_TRACE_EVENT_AUTO_OPEN_CLOSE_EVENT_H_ 82