1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/base/VisualEventTracer.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,232 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* Visual event tracer, creates a log of events on each thread for visualization */ 1.9 + 1.10 +/** 1.11 + * The event tracer code is by default disabled in both build and run time. 1.12 + * 1.13 + * To enable this code at build time, add --enable-visual-profiling to your 1.14 + * configure options. 1.15 + * 1.16 + * To enable this code at run time, export MOZ_TRACE_FILE env var with a 1.17 + * path to the file to write the log to. This is all you need to * produce 1.18 + * the log of all events instrumentation in the mozilla code. Check 1.19 + * MOZ_EVENT_TRACER_* macros below to add your own. 1.20 + * 1.21 + * To let the event tracer log only some events to save disk space, export 1.22 + * MOZ_PROFILING_EVENTS with comma separated list of event names you want 1.23 + * to record in the log. 1.24 + */ 1.25 + 1.26 +#ifndef VisualEventTracer_h___ 1.27 +#define VisualEventTracer_h___ 1.28 + 1.29 +#include <stdint.h> 1.30 +#include "mozilla/Attributes.h" 1.31 +#include "mozilla/GuardObjects.h" 1.32 + 1.33 +#ifdef MOZ_VISUAL_EVENT_TRACER 1.34 +#include "nsIVisualEventTracer.h" 1.35 + 1.36 +// Bind an object instance, usually |this|, to a name, usually URL or 1.37 +// host name, the instance deals with for its lifetime. The name string 1.38 +// is duplicated. 1.39 +// IMPORTANT: it is up to the caller to pass the correct static_cast 1.40 +// of the |instance| pointer to all these macros ; otherwise the linking 1.41 +// of events and objects will not work! 1.42 +// The name will show in details of the events on the timeline and also 1.43 +// will allow events filtering by host names, URLs etc. 1.44 +#define MOZ_EVENT_TRACER_NAME_OBJECT(instance, name) \ 1.45 + mozilla::eventtracer::Mark(mozilla::eventtracer::eName, instance, name) 1.46 + 1.47 +// The same as MOZ_EVENT_TRACER_NAME_OBJECT, just simplifies building 1.48 +// names when it consists of two parts 1.49 +#define MOZ_EVENT_TRACER_COMPOUND_NAME(instance, name, name2) \ 1.50 + mozilla::eventtracer::Mark(mozilla::eventtracer::eName, instance, name, name2) 1.51 + 1.52 + 1.53 +// Call the followings with the same |instance| reference as you have 1.54 +// previously called MOZ_EVENT_TRACER_NAME_OBJECT. 1.55 +// Let |name| be the name of the event happening, like "resolving", 1.56 +// "connecting", "loading" etc. 1.57 + 1.58 +// This will crate a single-point-in-time event marked with an arrow 1.59 +// on the timeline, this is a way to indicate an event without a duration. 1.60 +#define MOZ_EVENT_TRACER_MARK(instance, name) \ 1.61 + mozilla::eventtracer::Mark(mozilla::eventtracer::eShot, instance, name) 1.62 + 1.63 +// Following macros are used to log events with duration. 1.64 +// There always has to be complete WAIT,EXEC,DONE or EXEC,DONE 1.65 +// uninterrupted and non-interferring tuple(s) for an event to be correctly 1.66 +// shown on the timeline. Each can be called on any thread, the event tape is 1.67 +// finally displayed on the thread where it has been EXECuted. 1.68 + 1.69 +// Example of 3 phases usage for "HTTP request channel": 1.70 +// WAIT: we've just created the channel and called AsyncOpen on it 1.71 +// EXEC: we've just got first call to OnDataAvailable, so we are actually 1.72 +// receiving the content after some time like connection establising, 1.73 +// opening a cache entry, sending the GET request... 1.74 +// DONE: we've just got OnStopRequest call that indicates the content 1.75 +// has been completely delivered and the request is now finished 1.76 + 1.77 +// Indicate an event pending start, on the timeline this will 1.78 +// start the event's interval tape with a pale color, the time will 1.79 +// show in details. Usually used when an event is being posted or 1.80 +// we wait for a lock acquisition. 1.81 +// WAITING is not mandatory, some events don't have a pending phase. 1.82 +#define MOZ_EVENT_TRACER_WAIT(instance, name) \ 1.83 + mozilla::eventtracer::Mark(mozilla::eventtracer::eWait, instance, name) 1.84 + 1.85 +// Indicate start of an event actual execution, on the timeline this will 1.86 +// change the event's tape to a deeper color, the time will show in details. 1.87 +#define MOZ_EVENT_TRACER_EXEC(instance, name) \ 1.88 + mozilla::eventtracer::Mark(mozilla::eventtracer::eExec, instance, name) 1.89 + 1.90 +// Indicate the end of an event execution (the event has been done), 1.91 +// on the timeline this will end the event's tape and show the time in 1.92 +// event details. 1.93 +// NOTE: when the event duration is extremely short, like 1ms, it will convert 1.94 +// to an event w/o a duration - the same as MOZ_EVENT_TRACER_MARK would be used. 1.95 +#define MOZ_EVENT_TRACER_DONE(instance, name) \ 1.96 + mozilla::eventtracer::Mark(mozilla::eventtracer::eDone, instance, name) 1.97 + 1.98 +// The same meaning as the above macros, just for concurent events. 1.99 +// Concurent event means it can happen for the same instance on more 1.100 +// then just a single thread, e.g. a service method call, a global lock 1.101 +// acquisition, enter and release. 1.102 +#define MOZ_EVENT_TRACER_WAIT_THREADSAFE(instance, name) \ 1.103 + mozilla::eventtracer::Mark(mozilla::eventtracer::eWait | mozilla::eventtracer::eThreadConcurrent, instance, name) 1.104 +#define MOZ_EVENT_TRACER_EXEC_THREADSAFE(instance, name) \ 1.105 + mozilla::eventtracer::Mark(mozilla::eventtracer::eExec | mozilla::eventtracer::eThreadConcurrent, instance, name) 1.106 +#define MOZ_EVENT_TRACER_DONE_THREASAFE(instance, name) \ 1.107 + mozilla::eventtracer::Mark(mozilla::eventtracer::eDone | mozilla::eventtracer::eThreadConcurrent, instance, name) 1.108 + 1.109 +#else 1.110 + 1.111 +// MOZ_VISUAL_EVENT_TRACER disabled 1.112 + 1.113 +#define MOZ_EVENT_TRACER_NAME_OBJECT(instance, name) (void)0 1.114 +#define MOZ_EVENT_TRACER_COMPOUND_NAME(instance, name, name2) (void)0 1.115 +#define MOZ_EVENT_TRACER_MARK(instance, name) (void)0 1.116 +#define MOZ_EVENT_TRACER_WAIT(instance, name) (void)0 1.117 +#define MOZ_EVENT_TRACER_EXEC(instance, name) (void)0 1.118 +#define MOZ_EVENT_TRACER_DONE(instance, name) (void)0 1.119 +#define MOZ_EVENT_TRACER_WAIT_THREADSAFE(instance, name) (void)0 1.120 +#define MOZ_EVENT_TRACER_EXEC_THREADSAFE(instance, name) (void)0 1.121 +#define MOZ_EVENT_TRACER_DONE_THREASAFE(instance, name) (void)0 1.122 + 1.123 +#endif 1.124 + 1.125 + 1.126 +namespace mozilla { 1.127 +namespace eventtracer { 1.128 + 1.129 +// Initialize the event tracer engine, called automatically on XPCOM startup. 1.130 +void Init(); 1.131 + 1.132 +// Shuts the event tracer engine down and closes the log file, called 1.133 +// automatically during XPCOM shutdown. 1.134 +void Shutdown(); 1.135 + 1.136 +enum MarkType { 1.137 + eNone, // No operation, ignored 1.138 + eName, // This is used to bind an object instance with a name 1.139 + 1.140 + eShot, // An event with no duration 1.141 + eWait, // Start of waiting for execution (lock acquire, post...) 1.142 + eExec, // Start of the execution it self 1.143 + eDone, // End of the execution 1.144 + eLast, // Sentinel 1.145 + 1.146 + // Flags 1.147 + 1.148 + // The same object can execute the same event on several threads concurently 1.149 + eThreadConcurrent = 0x10000 1.150 +}; 1.151 + 1.152 +// Records an event on the calling thread. 1.153 +// @param aType 1.154 +// One of MarkType fields, can be bitwise or'ed with the flags. 1.155 +// @param aItem 1.156 +// Reference to the object we want to bind a name to or the event is 1.157 +// happening on. Can be actually anything, but valid poitners should 1.158 +// be used. 1.159 +// @param aText 1.160 +// Text of the name (for eName) or event's name for others. The string 1.161 +// is duplicated. 1.162 +// @param aText2 1.163 +// Optional second part of the instnace name, or event name. 1.164 +// Event filtering does apply only to the first part (aText). 1.165 +void Mark(uint32_t aType, void * aItem, 1.166 + const char * aText, const char * aText2 = 0); 1.167 + 1.168 + 1.169 +// Helper guard object. Use to mark an event in the constructor and a different 1.170 +// event in the destructor. 1.171 +// 1.172 +// Example: 1.173 +// int class::func() 1.174 +// { 1.175 +// AutoEventTracer tracer(this, eventtracer::eExec, eventtracer::eDone, "func"); 1.176 +// 1.177 +// do_something_taking_a_long_time(); 1.178 +// } 1.179 +class MOZ_STACK_CLASS AutoEventTracer 1.180 +{ 1.181 +public: 1.182 + AutoEventTracer(void * aInstance, 1.183 + uint32_t aTypeOn, // MarkType marked in constructor 1.184 + uint32_t aTypeOff, // MarkType marked in destructor 1.185 + const char * aName, 1.186 + const char * aName2 = 0 1.187 + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 1.188 + : mInstance(aInstance) 1.189 + , mName(aName) 1.190 + , mName2(aName2) 1.191 + , mTypeOn(aTypeOn) 1.192 + , mTypeOff(aTypeOff) 1.193 + { 1.194 + MOZ_GUARD_OBJECT_NOTIFIER_INIT; 1.195 + 1.196 + ::mozilla::eventtracer::Mark(mTypeOn, mInstance, mName, mName2); 1.197 + } 1.198 + 1.199 + ~AutoEventTracer() 1.200 + { 1.201 + ::mozilla::eventtracer::Mark(mTypeOff, mInstance, mName, mName2); 1.202 + } 1.203 + 1.204 +private: 1.205 + void * mInstance; 1.206 + const char * mName; 1.207 + const char * mName2; 1.208 + uint32_t mTypeOn; 1.209 + uint32_t mTypeOff; 1.210 + 1.211 + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER 1.212 +}; 1.213 + 1.214 +#ifdef MOZ_VISUAL_EVENT_TRACER 1.215 + 1.216 +// The scriptable class that drives the event tracer 1.217 + 1.218 +class VisualEventTracer : public nsIVisualEventTracer 1.219 +{ 1.220 + NS_DECL_ISUPPORTS 1.221 + NS_DECL_NSIVISUALEVENTTRACER 1.222 +}; 1.223 + 1.224 +#define NS_VISUALEVENTTRACER_CID \ 1.225 + { 0xb9e5e102, 0xc2f4, 0x497a, \ 1.226 + { 0xa6, 0xe4, 0x54, 0xde, 0xf3, 0x71, 0xf3, 0x9d } } 1.227 +#define NS_VISUALEVENTTRACER_CONTRACTID "@mozilla.org/base/visual-event-tracer;1" 1.228 +#define NS_VISUALEVENTTRACER_CLASSNAME "Visual Event Tracer" 1.229 + 1.230 +#endif 1.231 + 1.232 +} // eventtracer 1.233 +} // mozilla 1.234 + 1.235 +#endif /* VisualEventTracer_h___ */