summaryrefslogtreecommitdiff
path: root/indra/llcommon/lltimer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/lltimer.cpp')
-rwxr-xr-x[-rw-r--r--]indra/llcommon/lltimer.cpp168
1 files changed, 87 insertions, 81 deletions
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 25b768079b..76e892212a 100644..100755
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -2,31 +2,25 @@
* @file lltimer.cpp
* @brief Cross-platform objects for doing timing
*
- * $LicenseInfo:firstyear=2000&license=viewergpl$
- *
- * Copyright (c) 2000-2009, Linden Research, Inc.
- *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
* 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
+ * Copyright (C) 2010, Linden Research, Inc.
*
- * 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
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
*
- * 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.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -37,25 +31,18 @@
#include "u64.h"
#if LL_WINDOWS
-# define WIN32_LEAN_AND_MEAN
-# include <winsock2.h>
-# include <windows.h>
+# include "llwin32headerslean.h"
#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
-# include <errno.h>
+# include <errno.h>
# include <sys/time.h>
#else
# error "architecture not supported"
#endif
-
//
// Locally used constants
//
-const U32 SEC_PER_DAY = 86400;
-const F64 SEC_TO_MICROSEC = 1000000.f;
const U64 SEC_TO_MICROSEC_U64 = 1000000;
-const F64 USEC_TO_SEC_F64 = 0.000001;
-
//---------------------------------------------------------------------------
// Globals and statics
@@ -64,11 +51,6 @@ const F64 USEC_TO_SEC_F64 = 0.000001;
S32 gUTCOffset = 0; // viewer's offset from server UTC, in seconds
LLTimer* LLTimer::sTimer = NULL;
-F64 gClockFrequency = 0.0;
-F64 gClockFrequencyInv = 0.0;
-F64 gClocksToMicroseconds = 0.0;
-U64 gTotalTimeClockCount = 0;
-U64 gLastTotalTimeClockCount = 0;
//
// Forward declarations
@@ -89,7 +71,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
{
// max_yields is unused; just fiddle with it to avoid warnings.
max_yields = 0;
- ms_sleep(us / 1000);
+ ms_sleep((U32)(us / 1000));
return 0;
}
#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
@@ -196,7 +178,7 @@ U64 get_clock_count()
return clock_count.QuadPart - offset;
}
-F64 calc_clock_frequency(U32 uiMeasureMSecs)
+F64 calc_clock_frequency()
{
__int64 freq;
QueryPerformanceFrequency((LARGE_INTEGER *) &freq);
@@ -207,9 +189,9 @@ F64 calc_clock_frequency(U32 uiMeasureMSecs)
#if LL_LINUX || LL_DARWIN || LL_SOLARIS
// Both Linux and Mac use gettimeofday for accurate time
-F64 calc_clock_frequency(unsigned int uiMeasureMSecs)
+F64 calc_clock_frequency()
{
- return 1000000.0; // microseconds, so 1 Mhz.
+ return 1000000.0; // microseconds, so 1 MHz.
}
U64 get_clock_count()
@@ -222,56 +204,68 @@ U64 get_clock_count()
#endif
-void update_clock_frequencies()
+TimerInfo::TimerInfo()
+: mClockFrequency(0.0),
+ mTotalTimeClockCount(0),
+ mLastTotalTimeClockCount(0)
+{}
+
+void TimerInfo::update()
{
- gClockFrequency = calc_clock_frequency(50U);
- gClockFrequencyInv = 1.0/gClockFrequency;
- gClocksToMicroseconds = gClockFrequencyInv * SEC_TO_MICROSEC;
+ mClockFrequency = calc_clock_frequency();
+ mClockFrequencyInv = 1.0/mClockFrequency;
+ mClocksToMicroseconds = mClockFrequencyInv;
}
+TimerInfo& get_timer_info()
+{
+ static TimerInfo sTimerInfo;
+ return sTimerInfo;
+}
///////////////////////////////////////////////////////////////////////////////
// returns a U64 number that represents the number of
-// microseconds since the unix epoch - Jan 1, 1970
-U64 totalTime()
+// microseconds since the Unix epoch - Jan 1, 1970
+U64MicrosecondsImplicit totalTime()
{
U64 current_clock_count = get_clock_count();
- if (!gTotalTimeClockCount)
+ if (!get_timer_info().mTotalTimeClockCount || get_timer_info().mClocksToMicroseconds.value() == 0)
{
- update_clock_frequencies();
- gTotalTimeClockCount = current_clock_count;
+ get_timer_info().update();
+ get_timer_info().mTotalTimeClockCount = current_clock_count;
#if LL_WINDOWS
- // Synch us up with local time (even though we PROBABLY don't need to, this is how it was implemented)
+ // Sync us up with local time (even though we PROBABLY don't need to, this is how it was implemented)
// Unix platforms use gettimeofday so they are synced, although this probably isn't a good assumption to
// make in the future.
- gTotalTimeClockCount = (U64)(time(NULL) * gClockFrequency);
+ get_timer_info().mTotalTimeClockCount = (U64)(time(NULL) * get_timer_info().mClockFrequency);
#endif
// Update the last clock count
- gLastTotalTimeClockCount = current_clock_count;
+ get_timer_info().mLastTotalTimeClockCount = current_clock_count;
}
else
{
- if (current_clock_count >= gLastTotalTimeClockCount)
+ if (current_clock_count >= get_timer_info().mLastTotalTimeClockCount)
{
// No wrapping, we're all okay.
- gTotalTimeClockCount += current_clock_count - gLastTotalTimeClockCount;
+ get_timer_info().mTotalTimeClockCount += current_clock_count - get_timer_info().mLastTotalTimeClockCount;
}
else
{
// We've wrapped. Compensate correctly
- gTotalTimeClockCount += (0xFFFFFFFFFFFFFFFFULL - gLastTotalTimeClockCount) + current_clock_count;
+ get_timer_info().mTotalTimeClockCount += (0xFFFFFFFFFFFFFFFFULL - get_timer_info().mLastTotalTimeClockCount) + current_clock_count;
}
// Update the last clock count
- gLastTotalTimeClockCount = current_clock_count;
+ get_timer_info().mLastTotalTimeClockCount = current_clock_count;
}
// Return the total clock tick count in microseconds.
- return (U64)(gTotalTimeClockCount*gClocksToMicroseconds);
+ U64Microseconds time(get_timer_info().mTotalTimeClockCount*get_timer_info().mClocksToMicroseconds);
+ return time;
}
@@ -279,9 +273,9 @@ U64 totalTime()
LLTimer::LLTimer()
{
- if (!gClockFrequency)
+ if (!get_timer_info().mClockFrequency)
{
- update_clock_frequencies();
+ get_timer_info().update();
}
mStarted = TRUE;
@@ -289,20 +283,32 @@ LLTimer::LLTimer()
}
LLTimer::~LLTimer()
+{}
+
+// static
+void LLTimer::initClass()
+{
+ if (!sTimer) sTimer = new LLTimer;
+}
+
+// static
+void LLTimer::cleanupClass()
{
+ delete sTimer; sTimer = NULL;
}
// static
-U64 LLTimer::getTotalTime()
+U64MicrosecondsImplicit LLTimer::getTotalTime()
{
// simply call into the implementation function.
- return totalTime();
+ U64MicrosecondsImplicit total_time = totalTime();
+ return total_time;
}
// static
-F64 LLTimer::getTotalSeconds()
+F64SecondsImplicit LLTimer::getTotalSeconds()
{
- return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;
+ return F64Microseconds(U64_to_F64(getTotalTime()));
}
void LLTimer::reset()
@@ -349,43 +355,43 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)
}
-F64 LLTimer::getElapsedTimeF64() const
+F64SecondsImplicit LLTimer::getElapsedTimeF64() const
{
U64 last = mLastClockCount;
- return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;
+ return (F64)getElapsedTimeAndUpdate(last) * get_timer_info().mClockFrequencyInv;
}
-F32 LLTimer::getElapsedTimeF32() const
+F32SecondsImplicit LLTimer::getElapsedTimeF32() const
{
return (F32)getElapsedTimeF64();
}
-F64 LLTimer::getElapsedTimeAndResetF64()
+F64SecondsImplicit LLTimer::getElapsedTimeAndResetF64()
{
- return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;
+ return (F64)getElapsedTimeAndUpdate(mLastClockCount) * get_timer_info().mClockFrequencyInv;
}
-F32 LLTimer::getElapsedTimeAndResetF32()
+F32SecondsImplicit LLTimer::getElapsedTimeAndResetF32()
{
return (F32)getElapsedTimeAndResetF64();
}
///////////////////////////////////////////////////////////////////////////////
-void LLTimer::setTimerExpirySec(F32 expiration)
+void LLTimer::setTimerExpirySec(F32SecondsImplicit expiration)
{
mExpirationTicks = get_clock_count()
- + (U64)((F32)(expiration * gClockFrequency));
+ + (U64)((F32)(expiration * get_timer_info().mClockFrequency.value()));
}
-F32 LLTimer::getRemainingTimeF32() const
+F32SecondsImplicit LLTimer::getRemainingTimeF32() const
{
U64 cur_ticks = get_clock_count();
if (cur_ticks > mExpirationTicks)
{
return 0.0f;
}
- return F32((mExpirationTicks - cur_ticks) * gClockFrequencyInv);
+ return F32((mExpirationTicks - cur_ticks) * get_timer_info().mClockFrequencyInv);
}
@@ -398,7 +404,7 @@ BOOL LLTimer::checkExpirationAndReset(F32 expiration)
}
mExpirationTicks = cur_ticks
- + (U64)((F32)(expiration * gClockFrequency));
+ + (U64)((F32)(expiration * get_timer_info().mClockFrequency));
return TRUE;
}
@@ -454,7 +460,7 @@ BOOL LLTimer::knownBadTimer()
{
if (!wcscmp(pci_id, bad_pci_list[check]))
{
-// llwarns << "unreliable PCI chipset found!! " << pci_id << endl;
+// LL_WARNS() << "unreliable PCI chipset found!! " << pci_id << endl;
failed = TRUE;
break;
}
@@ -497,20 +503,20 @@ BOOL is_daylight_savings()
struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time)
{
- S32 pacific_offset_hours;
+ S32Hours pacific_offset_hours;
if (pacific_daylight_time)
{
- pacific_offset_hours = 7;
+ pacific_offset_hours = S32Hours(7);
}
else
{
- pacific_offset_hours = 8;
+ pacific_offset_hours = S32Hours(8);
}
// We subtract off the PST/PDT offset _before_ getting
// "UTC" time, because this will handle wrapping around
// for 5 AM UTC -> 10 PM PDT of the previous day.
- utc_time -= pacific_offset_hours * MIN_PER_HOUR * SEC_PER_MIN;
+ utc_time -= S32SecondsImplicit(pacific_offset_hours);
// Internal buffer to PST/PDT (see above)
struct tm* internal_time = gmtime(&utc_time);
@@ -527,7 +533,7 @@ struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time)
}
-void microsecondsToTimecodeString(U64 current_time, std::string& tcstring)
+void microsecondsToTimecodeString(U64MicrosecondsImplicit current_time, std::string& tcstring)
{
U64 hours;
U64 minutes;
@@ -549,9 +555,9 @@ void microsecondsToTimecodeString(U64 current_time, std::string& tcstring)
}
-void secondsToTimecodeString(F32 current_time, std::string& tcstring)
+void secondsToTimecodeString(F32SecondsImplicit current_time, std::string& tcstring)
{
- microsecondsToTimecodeString((U64)((F64)(SEC_TO_MICROSEC*current_time)), tcstring);
+ microsecondsToTimecodeString(current_time, tcstring);
}