PageRenderTime 37ms CodeModel.GetById 15ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/llviewerassetstats.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 328 lines | 105 code | 46 blank | 177 comment | 1 complexity | ed82841b4a11f4a512b280c61ec76260 MD5 | raw file
  1/** 
  2 * @file llviewerassetstats.h
  3 * @brief Client-side collection of asset request statistics
  4 *
  5 * $LicenseInfo:firstyear=2010&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#ifndef LL_LLVIEWERASSETSTATUS_H
 28#define	LL_LLVIEWERASSETSTATUS_H
 29
 30
 31#include "linden_common.h"
 32
 33#include "llpointer.h"
 34#include "llrefcount.h"
 35#include "llviewerassettype.h"
 36#include "llviewerassetstorage.h"
 37#include "llsimplestat.h"
 38#include "llsd.h"
 39
 40/**
 41 * @class LLViewerAssetStats
 42 * @brief Records performance aspects of asset access operations.
 43 *
 44 * This facility is derived from a very similar simulator-based
 45 * one, LLSimAssetStats.  It's function is to count asset access
 46 * operations and characterize response times.  Collected data
 47 * are binned in several dimensions:
 48 *
 49 *  - Asset types collapsed into a few aggregated categories
 50 *  - By simulator UUID
 51 *  - By transport mechanism (HTTP vs MessageSystem)
 52 *  - By persistence (temp vs non-temp)
 53 *
 54 * Statistics collected are fairly basic at this point:
 55 *
 56 *  - Counts of enqueue and dequeue operations
 57 *  - Min/Max/Mean of asset transfer operations
 58 *
 59 * This collector differs from the simulator-based on in a
 60 * number of ways:
 61 *
 62 *  - The front-end/back-end distinction doesn't exist in viewer
 63 *    code
 64 *  - Multiple threads must be safely accomodated in the viewer
 65 *
 66 * Access to results is by conversion to an LLSD with some standardized
 67 * key names.  The intent of this structure is that it be emitted as
 68 * standard syslog-based metrics formatting where it can be picked
 69 * up by interested parties.
 70 *
 71 * For convenience, a set of free functions in namespace
 72 * LLViewerAssetStatsFF is provided for conditional test-and-call
 73 * operations.
 74 */
 75class LLViewerAssetStats
 76{
 77public:
 78	enum EViewerAssetCategories
 79	{
 80		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP
 81		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP
 82		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP
 83		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP
 84		EVACWearableUDPGet,				//< Wearable GETs
 85		EVACSoundUDPGet,				//< Sound GETs
 86		EVACGestureUDPGet,				//< Gesture GETs
 87		EVACOtherGet,					//< Other GETs
 88		
 89		EVACCount						// Must be last
 90	};
 91
 92	/**
 93	 * Type for duration and other time values in the metrics.  Selected
 94	 * for compatibility with the pre-existing timestamp on the texture
 95	 * fetcher class, LLTextureFetch.
 96	 */
 97	typedef U64 duration_t;
 98
 99	/**
100	 * Type for the region identifier used in stats.  Currently uses
101	 * the region handle's type (a U64) rather than the regions's LLUUID
102	 * as the latter isn't available immediately.
103	 */
104	typedef U64 region_handle_t;
105
106	/**
107	 * @brief Collected data for a single region visited by the avatar.
108	 *
109	 * Fairly simple, for each asset bin enumerated above a count
110	 * of enqueue and dequeue operations and simple stats on response
111	 * times for completed requests.
112	 */
113	class PerRegionStats : public LLRefCount
114	{
115	public:
116		PerRegionStats(const region_handle_t region_handle)
117			: LLRefCount(),
118			  mRegionHandle(region_handle)
119			{
120				reset();
121			}
122
123		PerRegionStats(const PerRegionStats & src)
124			: LLRefCount(),
125			  mRegionHandle(src.mRegionHandle),
126			  mTotalTime(src.mTotalTime),
127			  mStartTimestamp(src.mStartTimestamp),
128			  mFPS(src.mFPS)
129			{
130				for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
131				{
132					mRequests[i] = src.mRequests[i];
133				}
134			}
135
136		// Default assignment and destructor are correct.
137		
138		void reset();
139
140		void merge(const PerRegionStats & src);
141		
142		// Apply current running time to total and reset start point.
143		// Return current timestamp as a convenience.
144		void accumulateTime(duration_t now);
145		
146	public:
147		region_handle_t		mRegionHandle;
148		duration_t			mTotalTime;
149		duration_t			mStartTimestamp;
150		LLSimpleStatMMM<>	mFPS;
151		
152		struct prs_group
153		{
154			LLSimpleStatCounter			mEnqueued;
155			LLSimpleStatCounter			mDequeued;
156			LLSimpleStatMMM<duration_t>	mResponse;
157		}
158		mRequests [EVACCount];
159	};
160
161public:
162	LLViewerAssetStats();
163	LLViewerAssetStats(const LLViewerAssetStats &);
164	// Default destructor is correct.
165	LLViewerAssetStats & operator=(const LLViewerAssetStats &);			// Not defined
166
167	// Clear all metrics data.  This leaves the currently-active region
168	// in place but with zero'd data for all metrics.  All other regions
169	// are removed from the collection map.
170	void reset();
171
172	// Set hidden region argument and establish context for subsequent
173	// collection calls.
174	void setRegion(region_handle_t region_handle);
175
176	// Asset GET Requests
177	void recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
178	void recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
179	void recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration);
180
181	// Frames-Per-Second Samples
182	void recordFPS(F32 fps);
183
184	// Merge a source instance into a destination instance.  This is
185	// conceptually an 'operator+=()' method:
186	// - counts are added
187	// - minimums are min'd
188	// - maximums are max'd
189	// - other scalars are ignored ('this' wins)
190	//
191	void merge(const LLViewerAssetStats & src);
192	
193	// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded)
194    // Returned LLSD is structured as follows:
195	//
196	// &stats_group = {
197	//   enqueued   : int,
198	//   dequeued   : int,
199	//   resp_count : int,
200	//   resp_min   : float,
201	//   resp_max   : float,
202	//   resp_mean  : float
203	// }
204	//
205	// &mmm_group = {
206	//   count : int,
207	//   min   : float,
208	//   max   : float,
209	//   mean  : float
210	// }
211	//
212	// {
213	//   duration: int
214	//   regions: {
215	//     $: {			// Keys are strings of the region's handle in hex
216	//       duration:                 : int,
217	//		 fps:					   : &mmm_group,
218	//       get_texture_temp_http     : &stats_group,
219	//       get_texture_temp_udp      : &stats_group,
220	//       get_texture_non_temp_http : &stats_group,
221	//       get_texture_non_temp_udp  : &stats_group,
222	//       get_wearable_udp          : &stats_group,
223	//       get_sound_udp             : &stats_group,
224	//       get_gesture_udp           : &stats_group,
225	//       get_other                 : &stats_group
226	//     }
227	//   }
228	// }
229	//
230	// @param	compact_output		If true, omits from conversion any mmm_block
231	//								or stats_block that would contain all zero data.
232	//								Useful for transmission when the receiver knows
233	//								what is expected and will assume zero for missing
234	//								blocks.
235	LLSD asLLSD(bool compact_output);
236
237protected:
238	typedef std::map<region_handle_t, LLPointer<PerRegionStats> > PerRegionContainer;
239
240	// Region of the currently-active region.  Always valid but may
241	// be zero after construction or when explicitly set.  Unchanged
242	// by a reset() call.
243	region_handle_t mRegionHandle;
244
245	// Pointer to metrics collection for currently-active region.  Always
246	// valid and unchanged after reset() though contents will be changed.
247	// Always points to a collection contained in mRegionStats.
248	LLPointer<PerRegionStats> mCurRegionStats;
249
250	// Metrics data for all regions during one collection cycle
251	PerRegionContainer mRegionStats;
252
253	// Time of last reset
254	duration_t mResetTimestamp;
255};
256
257
258/**
259 * Global stats collectors one for each independent thread where
260 * assets and other statistics are gathered.  The globals are
261 * expected to be created at startup time and then picked up by
262 * their respective threads afterwards.  A set of free functions
263 * are provided to access methods behind the globals while both
264 * minimally disrupting visual flow and supplying a description
265 * of intent.
266 *
267 * Expected thread assignments:
268 *
269 *  - Main:  main() program execution thread
270 *  - Thread1:  TextureFetch worker thread
271 */
272extern LLViewerAssetStats * gViewerAssetStatsMain;
273
274extern LLViewerAssetStats * gViewerAssetStatsThread1;
275
276namespace LLViewerAssetStatsFF
277{
278/**
279 * @brief Allocation and deallocation of globals.
280 *
281 * init() should be called before threads are started that will access it though
282 * you'll likely get away with calling it afterwards.  cleanup() should only be
283 * called after threads are shutdown to prevent races on the global pointers.
284 */
285void init();
286
287void cleanup();
288
289/**
290 * We have many timers, clocks etc. in the runtime.  This is the
291 * canonical timestamp for these metrics which is compatible with
292 * the pre-existing timestamping in the texture fetcher.
293 */
294inline LLViewerAssetStats::duration_t get_timestamp()
295{
296	return LLTimer::getTotalTime();
297}
298
299/**
300 * Region context, event and duration loggers for the Main thread.
301 */
302void set_region_main(LLViewerAssetStats::region_handle_t region_handle);
303
304void record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
305
306void record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
307
308void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp,
309						  LLViewerAssetStats::duration_t duration);
310
311void record_fps_main(F32 fps);
312
313
314/**
315 * Region context, event and duration loggers for Thread 1.
316 */
317void set_region_thread1(LLViewerAssetStats::region_handle_t region_handle);
318
319void record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
320
321void record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
322
323void record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp,
324						  LLViewerAssetStats::duration_t duration);
325
326} // namespace LLViewerAssetStatsFF
327
328#endif // LL_LLVIEWERASSETSTATUS_H