xpcom/base/VisualEventTracer.h

changeset 0
6474c204b198
     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___ */

mercurial