aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llstat.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/llcommon/llstat.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/llstat.cpp822
1 files changed, 822 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llstat.cpp b/linden/indra/llcommon/llstat.cpp
new file mode 100644
index 0000000..61893e2
--- /dev/null
+++ b/linden/indra/llcommon/llstat.cpp
@@ -0,0 +1,822 @@
1/**
2 * @file llstat.cpp
3 *
4 * Copyright (c) 2001-2007, Linden Research, Inc.
5 *
6 * The source code in this file ("Source Code") is provided by Linden Lab
7 * to you under the terms of the GNU General Public License, version 2.0
8 * ("GPL"), unless you have obtained a separate licensing agreement
9 * ("Other License"), formally executed by you and Linden Lab. Terms of
10 * the GPL can be found in doc/GPL-license.txt in this distribution, or
11 * online at http://secondlife.com/developers/opensource/gplv2
12 *
13 * There are special exceptions to the terms and conditions of the GPL as
14 * it is applied to this Source Code. View the full text of the exception
15 * in the file doc/FLOSS-exception.txt in this software distribution, or
16 * online at http://secondlife.com/developers/opensource/flossexception
17 *
18 * By copying, modifying or distributing this software, you acknowledge
19 * that you have read and understood your obligations described above,
20 * and agree to abide by those obligations.
21 *
22 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
23 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
24 * COMPLETENESS OR PERFORMANCE.
25 */
26
27#include "linden_common.h"
28
29#include "llstat.h"
30#include "llframetimer.h"
31#include "timing.h"
32
33class LLStatAccum::impl
34{
35public:
36 static const TimeScale IMPL_NUM_SCALES = (TimeScale)(SCALE_TWO_MINUTE + 1);
37 static U64 sScaleTimes[IMPL_NUM_SCALES];
38
39 BOOL mUseFrameTimer;
40
41 BOOL mRunning;
42 U64 mLastTime;
43
44 struct Bucket
45 {
46 F64 accum;
47 U64 endTime;
48
49 BOOL lastValid;
50 F64 lastAccum;
51 };
52
53 Bucket mBuckets[IMPL_NUM_SCALES];
54
55 BOOL mLastSampleValid;
56 F64 mLastSampleValue;
57
58
59 impl(bool useFrameTimer);
60
61 void reset(U64 when);
62
63 void sum(F64 value);
64 void sum(F64 value, U64 when);
65
66 F32 meanValue(TimeScale scale) const;
67
68 U64 getCurrentUsecs() const;
69 // Get current microseconds based on timer type
70};
71
72
73U64 LLStatAccum::impl::sScaleTimes[IMPL_NUM_SCALES] =
74{
75 USEC_PER_SEC * 1, // seconds
76 USEC_PER_SEC * 60, // minutes
77 USEC_PER_SEC * 60 * 2 // minutes
78#if 0
79 // enable these when more time scales are desired
80 USEC_PER_SEC * 60*60, // hours
81 USEC_PER_SEC * 24*60*60, // days
82 USEC_PER_SEC * 7*24*60*60, // weeks
83#endif
84};
85
86
87LLStatAccum::impl::impl(bool useFrameTimer)
88{
89 mUseFrameTimer = useFrameTimer;
90 mRunning = FALSE;
91 mLastSampleValid = FALSE;
92}
93
94void LLStatAccum::impl::reset(U64 when)
95{
96 mRunning = TRUE;
97 mLastTime = when;
98
99 for (int i = 0; i < IMPL_NUM_SCALES; ++i)
100 {
101 mBuckets[i].accum = 0.0;
102 mBuckets[i].endTime = when + sScaleTimes[i];
103 mBuckets[i].lastValid = FALSE;
104 }
105}
106
107void LLStatAccum::impl::sum(F64 value)
108{
109 sum(value, getCurrentUsecs());
110}
111
112void LLStatAccum::impl::sum(F64 value, U64 when)
113{
114 if (!mRunning)
115 {
116 reset(when);
117 return;
118 }
119 if (when < mLastTime)
120 {
121 llwarns << "LLStatAccum::sum clock has gone backwards from "
122 << mLastTime << " to " << when << ", resetting" << llendl;
123
124 reset(when);
125 return;
126 }
127
128 for (int i = 0; i < IMPL_NUM_SCALES; ++i)
129 {
130 Bucket& bucket = mBuckets[i];
131
132 if (when < bucket.endTime)
133 {
134 bucket.accum += value;
135 }
136 else
137 {
138 U64 timeScale = sScaleTimes[i];
139
140 U64 timeSpan = when - mLastTime;
141 // how long is this value for
142 U64 timeLeft = when - bucket.endTime;
143 // how much time is left after filling this bucket
144
145 if (timeLeft < timeScale)
146 {
147 F64 valueLeft = value * timeLeft / timeSpan;
148
149 bucket.lastValid = TRUE;
150 bucket.lastAccum = bucket.accum + (value - valueLeft);
151 bucket.accum = valueLeft;
152 bucket.endTime += timeScale;
153 }
154 else
155 {
156 U64 timeTail = timeLeft % timeScale;
157
158 bucket.lastValid = TRUE;
159 bucket.lastAccum = value * timeScale / timeSpan;
160 bucket.accum = value * timeTail / timeSpan;
161 bucket.endTime += (timeLeft - timeTail) + timeScale;
162 }
163 }
164 }
165
166 mLastTime = when;
167}
168
169
170F32 LLStatAccum::impl::meanValue(TimeScale scale) const
171{
172 if (!mRunning)
173 {
174 return 0.0;
175 }
176 if (scale < 0 || scale >= IMPL_NUM_SCALES)
177 {
178 llwarns << "llStatAccum::meanValue called for unsupported scale: "
179 << scale << llendl;
180 return 0.0;
181 }
182
183 const Bucket& bucket = mBuckets[scale];
184
185 F64 value = bucket.accum;
186 U64 timeLeft = bucket.endTime - mLastTime;
187 U64 scaleTime = sScaleTimes[scale];
188
189 if (bucket.lastValid)
190 {
191 value += bucket.lastAccum * timeLeft / scaleTime;
192 }
193 else if (timeLeft < scaleTime)
194 {
195 value *= scaleTime / (scaleTime - timeLeft);
196 }
197 else
198 {
199 value = 0.0;
200 }
201
202 return (F32)(value / scaleTime);
203}
204
205
206U64 LLStatAccum::impl::getCurrentUsecs() const
207{
208 if (mUseFrameTimer)
209 {
210 return LLFrameTimer::getTotalTime();
211 }
212 else
213 {
214 return totalTime();
215 }
216}
217
218
219
220
221
222LLStatAccum::LLStatAccum(bool useFrameTimer)
223 : m(* new impl(useFrameTimer))
224{
225}
226
227LLStatAccum::~LLStatAccum()
228{
229 delete &m;
230}
231
232F32 LLStatAccum::meanValue(TimeScale scale) const
233{
234 return m.meanValue(scale);
235}
236
237
238
239LLStatMeasure::LLStatMeasure(bool use_frame_timer)
240 : LLStatAccum(use_frame_timer)
241{
242}
243
244void LLStatMeasure::sample(F64 value)
245{
246 U64 when = m.getCurrentUsecs();
247
248 if (m.mLastSampleValid)
249 {
250 F64 avgValue = (value + m.mLastSampleValue) / 2.0;
251 F64 interval = (F64)(when - m.mLastTime);
252
253 m.sum(avgValue * interval, when);
254 }
255 else
256 {
257 m.reset(when);
258 }
259
260 m.mLastSampleValid = TRUE;
261 m.mLastSampleValue = value;
262}
263
264
265LLStatRate::LLStatRate(bool use_frame_timer)
266 : LLStatAccum(use_frame_timer)
267{
268}
269
270void LLStatRate::count(U32 value)
271{
272 m.sum((F64)value * impl::sScaleTimes[SCALE_SECOND]);
273}
274
275
276LLStatTime::LLStatTime(bool use_frame_timer)
277 : LLStatAccum(use_frame_timer)
278{
279}
280
281void LLStatTime::start()
282{
283 m.sum(0.0);
284}
285
286void LLStatTime::stop()
287{
288 U64 endTime = m.getCurrentUsecs();
289 m.sum((F64)(endTime - m.mLastTime), endTime);
290}
291
292
293
294LLTimer LLStat::sTimer;
295LLFrameTimer LLStat::sFrameTimer;
296
297LLStat::LLStat(const U32 num_bins, const BOOL use_frame_timer)
298{
299 llassert(num_bins > 0);
300 U32 i;
301 mUseFrameTimer = use_frame_timer;
302 mNumValues = 0;
303 mLastValue = 0.f;
304 mLastTime = 0.f;
305 mNumBins = num_bins;
306 mCurBin = (mNumBins-1);
307 mNextBin = 0;
308 mBins = new F32[mNumBins];
309 mBeginTime = new F64[mNumBins];
310 mTime = new F64[mNumBins];
311 mDT = new F32[mNumBins];
312 for (i = 0; i < mNumBins; i++)
313 {
314 mBins[i] = 0.f;
315 mBeginTime[i] = 0.0;
316 mTime[i] = 0.0;
317 mDT[i] = 0.f;
318 }
319}
320
321LLStat::~LLStat()
322{
323 delete[] mBins;
324 delete[] mBeginTime;
325 delete[] mTime;
326 delete[] mDT;
327}
328
329void LLStat::reset()
330{
331 U32 i;
332
333 mNumValues = 0;
334 mLastValue = 0.f;
335 mCurBin = (mNumBins-1);
336 delete[] mBins;
337 delete[] mBeginTime;
338 delete[] mTime;
339 delete[] mDT;
340 mBins = new F32[mNumBins];
341 mBeginTime = new F64[mNumBins];
342 mTime = new F64[mNumBins];
343 mDT = new F32[mNumBins];
344 for (i = 0; i < mNumBins; i++)
345 {
346 mBins[i] = 0.f;
347 mBeginTime[i] = 0.0;
348 mTime[i] = 0.0;
349 mDT[i] = 0.f;
350 }
351}
352
353void LLStat::setBeginTime(const F64 time)
354{
355 mBeginTime[mNextBin] = time;
356}
357
358void LLStat::addValueTime(const F64 time, const F32 value)
359{
360 if (mNumValues < mNumBins)
361 {
362 mNumValues++;
363 }
364
365 // Increment the bin counters.
366 mCurBin++;
367 if ((U32)mCurBin == mNumBins)
368 {
369 mCurBin = 0;
370 }
371 mNextBin++;
372 if ((U32)mNextBin == mNumBins)
373 {
374 mNextBin = 0;
375 }
376
377 mBins[mCurBin] = value;
378 mTime[mCurBin] = time;
379 mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]);
380 //this value is used to prime the min/max calls
381 mLastTime = mTime[mCurBin];
382 mLastValue = value;
383
384 // Set the begin time for the next stat segment.
385 mBeginTime[mNextBin] = mTime[mCurBin];
386 mTime[mNextBin] = mTime[mCurBin];
387 mDT[mNextBin] = 0.f;
388}
389
390void LLStat::start()
391{
392 if (mUseFrameTimer)
393 {
394 mBeginTime[mNextBin] = sFrameTimer.getElapsedSeconds();
395 }
396 else
397 {
398 mBeginTime[mNextBin] = sTimer.getElapsedTimeF64();
399 }
400}
401
402void LLStat::addValue(const F32 value)
403{
404 if (mNumValues < mNumBins)
405 {
406 mNumValues++;
407 }
408
409 // Increment the bin counters.
410 mCurBin++;
411 if ((U32)mCurBin == mNumBins)
412 {
413 mCurBin = 0;
414 }
415 mNextBin++;
416 if ((U32)mNextBin == mNumBins)
417 {
418 mNextBin = 0;
419 }
420
421 mBins[mCurBin] = value;
422 if (mUseFrameTimer)
423 {
424 mTime[mCurBin] = sFrameTimer.getElapsedSeconds();
425 }
426 else
427 {
428 mTime[mCurBin] = sTimer.getElapsedTimeF64();
429 }
430 mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]);
431
432 //this value is used to prime the min/max calls
433 mLastTime = mTime[mCurBin];
434 mLastValue = value;
435
436 // Set the begin time for the next stat segment.
437 mBeginTime[mNextBin] = mTime[mCurBin];
438 mTime[mNextBin] = mTime[mCurBin];
439 mDT[mNextBin] = 0.f;
440}
441
442
443F32 LLStat::getMax() const
444{
445 U32 i;
446 F32 current_max = mLastValue;
447 if (mNumBins == 0)
448 {
449 current_max = 0.f;
450 }
451 else
452 {
453 for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
454 {
455 // Skip the bin we're currently filling.
456 if (i == (U32)mNextBin)
457 {
458 continue;
459 }
460 if (mBins[i] > current_max)
461 {
462 current_max = mBins[i];
463 }
464 }
465 }
466 return current_max;
467}
468
469F32 LLStat::getMean() const
470{
471 U32 i;
472 F32 current_mean = 0.f;
473 U32 samples = 0;
474 for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
475 {
476 // Skip the bin we're currently filling.
477 if (i == (U32)mNextBin)
478 {
479 continue;
480 }
481 current_mean += mBins[i];
482 samples++;
483 }
484
485 // There will be a wrap error at 2^32. :)
486 if (samples != 0)
487 {
488 current_mean /= samples;
489 }
490 else
491 {
492 current_mean = 0.f;
493 }
494 return current_mean;
495}
496
497F32 LLStat::getMin() const
498{
499 U32 i;
500 F32 current_min = mLastValue;
501
502 if (mNumBins == 0)
503 {
504 current_min = 0.f;
505 }
506 else
507 {
508 for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
509 {
510 // Skip the bin we're currently filling.
511 if (i == (U32)mNextBin)
512 {
513 continue;
514 }
515 if (mBins[i] < current_min)
516 {
517 current_min = mBins[i];
518 }
519 }
520 }
521 return current_min;
522}
523
524F32 LLStat::getSum() const
525{
526 U32 i;
527 F32 sum = 0.f;
528 for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
529 {
530 // Skip the bin we're currently filling.
531 if (i == (U32)mNextBin)
532 {
533 continue;
534 }
535 sum += mBins[i];
536 }
537
538 return sum;
539}
540
541F32 LLStat::getSumDuration() const
542{
543 U32 i;
544 F32 sum = 0.f;
545 for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
546 {
547 // Skip the bin we're currently filling.
548 if (i == (U32)mNextBin)
549 {
550 continue;
551 }
552 sum += mDT[i];
553 }
554
555 return sum;
556}
557
558F32 LLStat::getPrev(S32 age) const
559{
560 S32 bin;
561 bin = mCurBin - age;
562
563 while (bin < 0)
564 {
565 bin += mNumBins;
566 }
567
568 if (bin == mNextBin)
569 {
570 // Bogus for bin we're currently working on.
571 return 0.f;
572 }
573 return mBins[bin];
574}
575
576F32 LLStat::getPrevPerSec(S32 age) const
577{
578 S32 bin;
579 bin = mCurBin - age;
580
581 while (bin < 0)
582 {
583 bin += mNumBins;
584 }
585
586 if (bin == mNextBin)
587 {
588 // Bogus for bin we're currently working on.
589 return 0.f;
590 }
591 return mBins[bin] / mDT[bin];
592}
593
594F64 LLStat::getPrevBeginTime(S32 age) const
595{
596 S32 bin;
597 bin = mCurBin - age;
598
599 while (bin < 0)
600 {
601 bin += mNumBins;
602 }
603
604 if (bin == mNextBin)
605 {
606 // Bogus for bin we're currently working on.
607 return 0.f;
608 }
609
610 return mBeginTime[bin];
611}
612
613F64 LLStat::getPrevTime(S32 age) const
614{
615 S32 bin;
616 bin = mCurBin - age;
617
618 while (bin < 0)
619 {
620 bin += mNumBins;
621 }
622
623 if (bin == mNextBin)
624 {
625 // Bogus for bin we're currently working on.
626 return 0.f;
627 }
628
629 return mTime[bin];
630}
631
632F32 LLStat::getBin(S32 bin) const
633{
634 return mBins[bin];
635}
636
637F32 LLStat::getBinPerSec(S32 bin) const
638{
639 return mBins[bin] / mDT[bin];
640}
641
642F64 LLStat::getBinBeginTime(S32 bin) const
643{
644 return mBeginTime[bin];
645}
646
647F64 LLStat::getBinTime(S32 bin) const
648{
649 return mTime[bin];
650}
651
652F32 LLStat::getCurrent() const
653{
654 return mBins[mCurBin];
655}
656
657F32 LLStat::getCurrentPerSec() const
658{
659 return mBins[mCurBin] / mDT[mCurBin];
660}
661
662F64 LLStat::getCurrentBeginTime() const
663{
664 return mBeginTime[mCurBin];
665}
666
667F64 LLStat::getCurrentTime() const
668{
669 return mTime[mCurBin];
670}
671
672F32 LLStat::getCurrentDuration() const
673{
674 return mDT[mCurBin];
675}
676
677F32 LLStat::getMeanPerSec() const
678{
679 U32 i;
680 F32 value = 0.f;
681 F32 dt = 0.f;
682
683 for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
684 {
685 // Skip the bin we're currently filling.
686 if (i == (U32)mNextBin)
687 {
688 continue;
689 }
690 value += mBins[i];
691 dt += mDT[i];
692 }
693
694 if (dt > 0.f)
695 {
696 return value/dt;
697 }
698 else
699 {
700 return 0.f;
701 }
702}
703
704F32 LLStat::getMeanDuration() const
705{
706 F32 dur = 0.0f;
707 U32 count = 0;
708 for (U32 i=0; (i < mNumBins) && (i < mNumValues); i++)
709 {
710 if (i == (U32)mNextBin)
711 {
712 continue;
713 }
714 dur += mDT[i];
715 count++;
716 }
717
718 if (count > 0)
719 {
720 dur /= F32(count);
721 return dur;
722 }
723 else
724 {
725 return 0.f;
726 }
727}
728
729F32 LLStat::getMaxPerSec() const
730{
731 U32 i;
732 F32 value;
733
734 if (mNextBin != 0)
735 {
736 value = mBins[0]/mDT[0];
737 }
738 else if (mNumValues > 0)
739 {
740 value = mBins[1]/mDT[1];
741 }
742 else
743 {
744 value = 0.f;
745 }
746
747 for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
748 {
749 // Skip the bin we're currently filling.
750 if (i == (U32)mNextBin)
751 {
752 continue;
753 }
754 value = llmax(value, mBins[i]/mDT[i]);
755 }
756 return value;
757}
758
759F32 LLStat::getMinPerSec() const
760{
761 U32 i;
762 F32 value;
763
764 if (mNextBin != 0)
765 {
766 value = mBins[0]/mDT[0];
767 }
768 else if (mNumValues > 0)
769 {
770 value = mBins[1]/mDT[1];
771 }
772 else
773 {
774 value = 0.f;
775 }
776
777 for (i = 0; (i < mNumBins) && (i < mNumValues); i++)
778 {
779 // Skip the bin we're currently filling.
780 if (i == (U32)mNextBin)
781 {
782 continue;
783 }
784 value = llmin(value, mBins[i]/mDT[i]);
785 }
786 return value;
787}
788
789F32 LLStat::getMinDuration() const
790{
791 F32 dur = 0.0f;
792 for (U32 i=0; (i < mNumBins) && (i < mNumValues); i++)
793 {
794 dur = llmin(dur, mDT[i]);
795 }
796 return dur;
797}
798
799U32 LLStat::getNumValues() const
800{
801 return mNumValues;
802}
803
804S32 LLStat::getNumBins() const
805{
806 return mNumBins;
807}
808
809S32 LLStat::getCurBin() const
810{
811 return mCurBin;
812}
813
814S32 LLStat::getNextBin() const
815{
816 return mNextBin;
817}
818
819F64 LLStat::getLastTime() const
820{
821 return mLastTime;
822}