123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- /**
- * @file llstat.cpp
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "linden_common.h"
- #include "llstat.h"
- #include "llframetimer.h"
- #include "llsdserialize.h"
- LLTimer LLStat::sTimer;
- LLFrameTimer LLStat::sFrameTimer;
- LLStat::LLStat(U32 num_bins, bool use_frame_timer)
- : mUseFrameTimer(use_frame_timer),
- mNumValues(0),
- mLastValue(0.f),
- mLastTime(0.f),
- mNumBins(num_bins),
- mCurBin(num_bins - 1),
- mNextBin(0)
- {
- llassert_always(mNumBins > 0);
- init();
- }
- LLStat::~LLStat()
- {
- delete[] mBins;
- delete[] mBeginTime;
- delete[] mTime;
- delete[] mDT;
- }
- void LLStat::init()
- {
- mBins = new F32[mNumBins];
- mBeginTime = new F64[mNumBins];
- mTime = new F64[mNumBins];
- mDT = new F32[mNumBins];
- for (U32 i = 0; i < mNumBins; ++i)
- {
- mBins[i] = 0.f;
- mBeginTime[i] = 0.0;
- mTime[i] = 0.0;
- mDT[i] = 0.f;
- }
- }
- void LLStat::reset()
- {
- mNumValues = 0;
- mLastValue = 0.f;
- mCurBin = mNumBins - 1;
- delete[] mBins;
- delete[] mBeginTime;
- delete[] mTime;
- delete[] mDT;
- init();
- }
- void LLStat::addValueTime(F64 time, F32 value)
- {
- if (mNumValues < mNumBins)
- {
- ++mNumValues;
- }
- // Increment the bin counters.
- if ((U32)(++mCurBin) == mNumBins)
- {
- mCurBin = 0;
- }
- if ((U32)(++mNextBin) == mNumBins)
- {
- mNextBin = 0;
- }
- mBins[mCurBin] = value;
- mTime[mCurBin] = time;
- mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]);
- // This value is used to prime the min/max calls
- mLastTime = mTime[mCurBin];
- mLastValue = value;
- // Set the begin time for the next stat segment.
- mBeginTime[mNextBin] = mTime[mCurBin];
- mTime[mNextBin] = mTime[mCurBin];
- mDT[mNextBin] = 0.f;
- }
- void LLStat::start()
- {
- if (mUseFrameTimer)
- {
- mBeginTime[mNextBin] = sFrameTimer.getElapsedSeconds();
- }
- else
- {
- mBeginTime[mNextBin] = sTimer.getElapsedTimeF64();
- }
- }
- void LLStat::addValue(F32 value)
- {
- if (mNumValues < mNumBins)
- {
- ++mNumValues;
- }
- // Increment the bin counters.
- if ((U32)(++mCurBin) == mNumBins)
- {
- mCurBin = 0;
- }
- if ((U32)(++mNextBin) == mNumBins)
- {
- mNextBin = 0;
- }
- mBins[mCurBin] = value;
- if (mUseFrameTimer)
- {
- mTime[mCurBin] = sFrameTimer.getElapsedSeconds();
- }
- else
- {
- mTime[mCurBin] = sTimer.getElapsedTimeF64();
- }
- mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]);
- // This value is used to prime the min/max calls
- mLastTime = mTime[mCurBin];
- mLastValue = value;
- // Set the begin time for the next stat segment.
- mBeginTime[mNextBin] = mTime[mCurBin];
- mTime[mNextBin] = mTime[mCurBin];
- mDT[mNextBin] = 0.f;
- }
- F32 LLStat::getMax() const
- {
- F32 current_max = mLastValue;
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- // Skip the bin we are currently filling.
- if (i != (U32)mNextBin && mBins[i] > current_max)
- {
- current_max = mBins[i];
- }
- }
- return current_max;
- }
- F32 LLStat::getMean() const
- {
- F32 current_mean = 0.f;
- U32 samples = 0;
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- // Skip the bin we are currently filling.
- if (i != (U32)mNextBin)
- {
- current_mean += mBins[i];
- ++samples;
- }
- }
- return samples != 0 ? current_mean / (F32)samples : 0.f;
- }
- F32 LLStat::getMin() const
- {
- F32 current_min = mLastValue;
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- // Skip the bin we are currently filling.
- if (i != (U32)mNextBin && mBins[i] < current_min)
- {
- current_min = mBins[i];
- }
- }
- return current_min;
- }
- F32 LLStat::getSum() const
- {
- F32 sum = 0.f;
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- // Skip the bin we are currently filling.
- if (i != (U32)mNextBin)
- {
- sum += mBins[i];
- }
- }
- return sum;
- }
- F32 LLStat::getSumDuration() const
- {
- F32 sum = 0.f;
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- // Skip the bin we are currently filling.
- if (i != (U32)mNextBin)
- {
- sum += mDT[i];
- }
- }
- return sum;
- }
- F32 LLStat::getPrev(S32 age) const
- {
- S32 bin = mCurBin - age;
- while (bin < 0)
- {
- bin += mNumBins;
- }
- // Bogus for bin we are currently working on, so return 0 in that case
- return bin == mNextBin ? 0.f : mBins[bin];
- }
- F32 LLStat::getPrevPerSec(S32 age) const
- {
- S32 bin = mCurBin - age;
- while (bin < 0)
- {
- bin += mNumBins;
- }
- // Bogus for bin we are currently working on, so return 0 in that case
- return bin == mNextBin || mDT[bin] == 0.f ? 0.f : mBins[bin] / mDT[bin];
- }
- F64 LLStat::getPrevBeginTime(S32 age) const
- {
- S32 bin = mCurBin - age;
- while (bin < 0)
- {
- bin += mNumBins;
- }
- // Bogus for bin we are currently working on, so return 0 in that case
- return bin == mNextBin ? 0.0 : mBeginTime[bin];
- }
- F64 LLStat::getPrevTime(S32 age) const
- {
- S32 bin = mCurBin - age;
- while (bin < 0)
- {
- bin += mNumBins;
- }
- // Bogus for bin we are currently working on, so return 0 in that case
- return bin == mNextBin ? 0.0 : mTime[bin];
- }
- F32 LLStat::getMeanPerSec() const
- {
- F32 value = 0.f;
- F32 dt = 0.f;
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- // Skip the bin we are currently filling.
- if (i != (U32)mNextBin)
- {
- value += mBins[i];
- dt += mDT[i];
- }
- }
- return dt > 0.f ? value / dt : 0.f;
- }
- F32 LLStat::getMeanDuration() const
- {
- F32 dur = 0.f;
- U32 count = 0;
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- if (i == (U32)mNextBin)
- {
- continue;
- }
- dur += mDT[i];
- ++count;
- }
- return count > 0 ? dur / (F32)count : 0.f;
- }
- F32 LLStat::getMaxPerSec() const
- {
- F32 value;
- if (mNextBin != 0 && mDT[0] != 0.f)
- {
- value = mBins[0] / mDT[0];
- }
- else if (mNumValues > 0 && mDT[1] != 0.f)
- {
- value = mBins[1] / mDT[1];
- }
- else
- {
- value = 0.f;
- }
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- F32 dt = mDT[i];
- // Skip the bin we are currently filling.
- if (i != (U32)mNextBin && dt > 0.f)
- {
- value = llmax(value, mBins[i] / dt);
- }
- }
- return value;
- }
- F32 LLStat::getMinPerSec() const
- {
- F32 value;
- if (mNextBin != 0 && mDT[0] != 0.f)
- {
- value = mBins[0] / mDT[0];
- }
- else if (mNumValues > 0 && mDT[1] != 0.f)
- {
- value = mBins[1] / mDT[1];
- }
- else
- {
- value = 0.f;
- }
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- F32 dt = mDT[i];
- // Skip the bin we are currently filling.
- if (i != (U32)mNextBin && dt > 0.f)
- {
- value = llmin(value, mBins[i] / dt);
- }
- }
- return value;
- }
- F32 LLStat::getMinDuration() const
- {
- F32 dur = 0.f;
- for (U32 i = 0; i < mNumBins && i < mNumValues; ++i)
- {
- dur = llmin(dur, mDT[i]);
- }
- return dur;
- }
|