diff options
Diffstat (limited to '')
-rw-r--r-- | xpcom/build/perfprobe.h | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/xpcom/build/perfprobe.h b/xpcom/build/perfprobe.h new file mode 100644 index 0000000000..e5a0382322 --- /dev/null +++ b/xpcom/build/perfprobe.h @@ -0,0 +1,198 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * A mechanism for interacting with operating system-provided + * debugging/profiling tools such as Microsoft EWT/Windows Performance Toolkit. + */ + +#ifndef mozilla_perfprobe_h +#define mozilla_perfprobe_h + +#if !defined(XP_WIN) +# error "For the moment, perfprobe.h is defined only for Windows platforms" +#endif + +#include "nsError.h" +#include "nsString.h" +#include "mozilla/Logging.h" +#include "nsTArray.h" +#include <windows.h> +#undef GetStartupInfo // Prevent Windows from polluting global namespace +#include <wmistr.h> +#include <evntrace.h> + +namespace mozilla { +namespace probes { + +class ProbeManager; + +/** + * A data structure supporting a trigger operation that can be used to + * send information to the operating system. + */ + +class Probe { + public: + NS_INLINE_DECL_REFCOUNTING(Probe) + + /** + * Trigger the event. + * + * Note: Can be called from any thread. + */ + nsresult Trigger(); + + protected: + ~Probe(){}; + + Probe(const nsCID& aGUID, const nsACString& aName, ProbeManager* aManager); + friend class ProbeManager; + + protected: + /** + * The system GUID associated to this probe. See the documentation + * of |ProbeManager::Make| for more details. + */ + const GUID mGUID; + + /** + * The name of this probe. See the documentation + * of |ProbeManager::Make| for more details. + */ + const nsCString mName; + + /** + * The ProbeManager managing this probe. + * + * Note: This is a weak reference to avoid a useless cycle. + */ + class ProbeManager* mManager; +}; + +/** + * A manager for a group of probes. + * + * You can have several managers in one application, provided that they all + * have distinct IDs and names. However, having more than 2 is considered a bad + * practice. + */ +class ProbeManager { + public: + NS_INLINE_DECL_REFCOUNTING(ProbeManager) + + /** + * Create a new probe manager. + * + * This constructor should be called from the main thread. + * + * @param aApplicationUID The unique ID of the probe. Under Windows, this + * unique ID must have been previously registered using an external tool. + * See MyCategory on http://msdn.microsoft.com/en-us/library/aa364100.aspx + * @param aApplicationName A name for the probe. Currently used only for + * logging purposes. In the future, may be attached to the data sent to the + * operating system. + * + * Note: If two ProbeManagers are constructed with the same uid and/or name, + * behavior is unspecified. + */ + ProbeManager(const nsCID& aApplicationUID, + const nsACString& aApplicationName); + + /** + * Acquire a probe. + * + * Note: Only probes acquired before the call to SetReady are taken into + * account + * Note: Can be called only from the main thread. + * + * @param aEventUID The unique ID of the probe. Under Windows, this unique + * ID must have been previously registered using an external tool. + * See MyCategory on http://msdn.microsoft.com/en-us/library/aa364100.aspx + * @param aEventName A name for the probe. Currently used only for logging + * purposes. In the + * future, may be attached to the data sent to the operating system. + * @return Either |null| in case of error or a valid |Probe*|. + * + * Note: If this method is called twice with the same uid and/or name, + * behavior is undefined. + */ + already_AddRefed<Probe> GetProbe(const nsCID& aEventUID, + const nsACString& aEventName); + + /** + * Start/stop the measuring session. + * + * This method should be called from the main thread. + * + * Note that starting an already started probe manager has no effect, + * nor does stopping an already stopped probe manager. + */ + nsresult StartSession(); + nsresult StopSession(); + + /** + * @return true If measures are currently on, i.e. if triggering probes is any + * is useful. You do not have to check this before triggering a probe, unless + * this can avoid complex computations. + */ + bool IsActive(); + + protected: + ~ProbeManager(); + + nsresult StartSession(nsTArray<RefPtr<Probe>>& aProbes); + nsresult Init(const nsCID& aApplicationUID, + const nsACString& aApplicationName); + + protected: + /** + * `true` if a session is in activity, `false` otherwise. + */ + bool mIsActive; + + /** + * The UID of this manager. + * See documentation above for registration steps that you + * may have to take. + */ + nsCID mApplicationUID; + + /** + * The name of the application. + */ + nsCString mApplicationName; + + /** + * All the probes that have been created for this manager. + */ + nsTArray<RefPtr<Probe>> mAllProbes; + + /** + * Handle used for triggering events + */ + TRACEHANDLE mSessionHandle; + + /** + * Handle used for registration/unregistration + */ + TRACEHANDLE mRegistrationHandle; + + /** + * `true` if initialization has been performed, `false` until then. + */ + bool mInitialized; + + friend class Probe; // Needs to access |mSessionHandle| + friend ULONG WINAPI ControlCallback(WMIDPREQUESTCODE aRequestCode, + PVOID aContext, ULONG* aReserved, + PVOID aBuffer); // Sets |mSessionHandle| +}; + +} // namespace probes +} // namespace mozilla + +#endif // mozilla_perfprobe_h |