1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/telemetry/TelemetryStopwatch.jsm Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,133 @@ 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 file, 1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +const Cc = Components.classes; 1.9 +const Ci = Components.interfaces; 1.10 +const Cu = Components.utils; 1.11 + 1.12 +this.EXPORTED_SYMBOLS = ["TelemetryStopwatch"]; 1.13 + 1.14 +let Telemetry = Cc["@mozilla.org/base/telemetry;1"] 1.15 + .getService(Ci.nsITelemetry); 1.16 + 1.17 +// simpleTimers are directly associated with a histogram 1.18 +// name. objectTimers are associated with an object _and_ 1.19 +// a histogram name. 1.20 +let simpleTimers = {}; 1.21 +let objectTimers = new WeakMap(); 1.22 + 1.23 +this.TelemetryStopwatch = { 1.24 + /** 1.25 + * Starts a timer associated with a telemetry histogram. The timer can be 1.26 + * directly associated with a histogram, or with a pair of a histogram and 1.27 + * an object. 1.28 + * 1.29 + * @param aHistogram a string which must be a valid histogram name 1.30 + * from TelemetryHistograms.h 1.31 + * 1.32 + * @param aObj Optional parameter. If specified, the timer is associated 1.33 + * with this object, meaning that multiple timers for a same 1.34 + * histogram may be run concurrently, as long as they are 1.35 + * associated with different objects. 1.36 + * 1.37 + * @return true if the timer was successfully started, false otherwise. If a 1.38 + * timer already exists, it can't be started again, and the existing 1.39 + * one will be cleared in order to avoid measurements errors. 1.40 + */ 1.41 + start: function(aHistogram, aObj) { 1.42 + if (!validTypes(aHistogram, aObj)) 1.43 + return false; 1.44 + 1.45 + let timers; 1.46 + if (aObj) { 1.47 + timers = objectTimers.get(aObj, {}); 1.48 + objectTimers.set(aObj, timers); 1.49 + } else { 1.50 + timers = simpleTimers; 1.51 + } 1.52 + 1.53 + if (timers.hasOwnProperty(aHistogram)) { 1.54 + delete timers[aHistogram]; 1.55 + Cu.reportError("TelemetryStopwatch: key \"" + 1.56 + aHistogram + "\" was already initialized"); 1.57 + return false; 1.58 + } 1.59 + 1.60 + timers[aHistogram] = Date.now(); 1.61 + return true; 1.62 + }, 1.63 + 1.64 + /** 1.65 + * Deletes the timer associated with a telemetry histogram. The timer can be 1.66 + * directly associated with a histogram, or with a pair of a histogram and 1.67 + * an object. Important: Only use this method when a legitimate cancellation 1.68 + * should be done. 1.69 + * 1.70 + * @param aHistogram a string which must be a valid histogram name 1.71 + * from TelemetryHistograms.json 1.72 + * 1.73 + * @param aObj Optional parameter. If specified, the timer is associated 1.74 + * with this object, meaning that multiple timers for a same 1.75 + * histogram may be run concurrently, as long as they are 1.76 + * associated with different objects. 1.77 + * 1.78 + * @return true if the timer exist and it was cleared, false otherwise. 1.79 + */ 1.80 + cancel: function ts_cancel(aHistogram, aObj) { 1.81 + if (!validTypes(aHistogram, aObj)) 1.82 + return false; 1.83 + 1.84 + let timers = aObj 1.85 + ? objectTimers.get(aObj, {}) 1.86 + : simpleTimers; 1.87 + 1.88 + if (timers.hasOwnProperty(aHistogram)) { 1.89 + delete timers[aHistogram]; 1.90 + return true; 1.91 + } 1.92 + 1.93 + return false; 1.94 + }, 1.95 + 1.96 + /** 1.97 + * Stops the timer associated with the given histogram (and object), 1.98 + * calculates the time delta between start and finish, and adds the value 1.99 + * to the histogram. 1.100 + * 1.101 + * @param aHistogram a string which must be a valid histogram name 1.102 + * from TelemetryHistograms.h. If an invalid name 1.103 + * is given, the function will throw. 1.104 + * 1.105 + * @param aObj Optional parameter which associates the histogram timer with 1.106 + * the given object. 1.107 + * 1.108 + * @return true if the timer was succesfully stopped and the data was 1.109 + * added to the histogram, false otherwise. 1.110 + */ 1.111 + finish: function(aHistogram, aObj) { 1.112 + if (!validTypes(aHistogram, aObj)) 1.113 + return false; 1.114 + 1.115 + let timers = aObj 1.116 + ? objectTimers.get(aObj, {}) 1.117 + : simpleTimers; 1.118 + 1.119 + let start = timers[aHistogram]; 1.120 + delete timers[aHistogram]; 1.121 + 1.122 + if (start) { 1.123 + let delta = Date.now() - start; 1.124 + let histogram = Telemetry.getHistogramById(aHistogram); 1.125 + histogram.add(delta); 1.126 + return true; 1.127 + } 1.128 + 1.129 + return false; 1.130 + } 1.131 +} 1.132 + 1.133 +function validTypes(aKey, aObj) { 1.134 + return (typeof aKey == "string") && 1.135 + (aObj === undefined || typeof aObj == "object"); 1.136 +}