summaryrefslogtreecommitdiff
path: root/indra/llcommon/lltimer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/lltimer.cpp')
-rw-r--r--indra/llcommon/lltimer.cpp144
1 files changed, 67 insertions, 77 deletions
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 3d05699cd6..38054b636e 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -2,30 +2,25 @@
* @file lltimer.cpp
* @brief Cross-platform objects for doing timing
*
- * $LicenseInfo:firstyear=2000&license=viewergpl$
- *
- * Copyright (c) 2000-2007, 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://secondlife.com/developers/opensource/gplv2
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * 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.
*
- * 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://secondlife.com/developers/opensource/flossexception
+ * 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.
*
- * 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.
+ * 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
*
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -83,15 +78,20 @@ void ms_sleep(U32 ms)
{
Sleep(ms);
}
+
+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);
+ return 0;
+}
#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
-void ms_sleep(U32 ms)
+static void _sleep_loop(struct timespec& thiswait)
{
- long mslong = ms; // tv_nsec is a long
- struct timespec thiswait, nextwait;
+ struct timespec nextwait;
bool sleep_more = false;
- thiswait.tv_sec = ms / 1000;
- thiswait.tv_nsec = (mslong % 1000) * 1000000l;
do {
int result = nanosleep(&thiswait, &nextwait);
@@ -127,6 +127,44 @@ void ms_sleep(U32 ms)
}
} while (sleep_more);
}
+
+U32 micro_sleep(U64 us, U32 max_yields)
+{
+ U64 start = get_clock_count();
+ // This is kernel dependent. Currently, our kernel generates software clock
+ // interrupts at 250 Hz (every 4,000 microseconds).
+ const U64 KERNEL_SLEEP_INTERVAL_US = 4000;
+
+ S32 num_sleep_intervals = (us - (KERNEL_SLEEP_INTERVAL_US >> 1)) / KERNEL_SLEEP_INTERVAL_US;
+ if (num_sleep_intervals > 0)
+ {
+ U64 sleep_time = (num_sleep_intervals * KERNEL_SLEEP_INTERVAL_US) - (KERNEL_SLEEP_INTERVAL_US >> 1);
+ struct timespec thiswait;
+ thiswait.tv_sec = sleep_time / 1000000;
+ thiswait.tv_nsec = (sleep_time % 1000000) * 1000l;
+ _sleep_loop(thiswait);
+ }
+
+ U64 current_clock = get_clock_count();
+ U32 yields = 0;
+ while ( (yields < max_yields)
+ && (current_clock - start < us) )
+ {
+ sched_yield();
+ ++yields;
+ current_clock = get_clock_count();
+ }
+ return yields;
+}
+
+void ms_sleep(U32 ms)
+{
+ long mslong = ms; // tv_nsec is a long
+ struct timespec thiswait;
+ thiswait.tv_sec = ms / 1000;
+ thiswait.tv_nsec = (mslong % 1000) * 1000000l;
+ _sleep_loop(thiswait);
+}
#else
# error "architecture not supported"
#endif
@@ -165,7 +203,7 @@ F64 calc_clock_frequency(U32 uiMeasureMSecs)
// Both Linux and Mac use gettimeofday for accurate time
F64 calc_clock_frequency(unsigned int uiMeasureMSecs)
{
- return 1000000.0; // microseconds, so 1 Mhz.
+ return 1000000.0; // microseconds, so 1 MHz.
}
U64 get_clock_count()
@@ -483,7 +521,7 @@ struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time)
}
-void microsecondsToTimecodeString(U64 current_time, char *tcstring)
+void microsecondsToTimecodeString(U64 current_time, std::string& tcstring)
{
U64 hours;
U64 minutes;
@@ -501,61 +539,13 @@ void microsecondsToTimecodeString(U64 current_time, char *tcstring)
subframes = current_time / (U64)42;
subframes %= 100;
- sprintf(tcstring,"%3.3d:%2.2d:%2.2d:%2.2d.%2.2d",(int)hours,(int)minutes,(int)seconds,(int)frames,(int)subframes); /* Flawfinder: ignore */
+ tcstring = llformat("%3.3d:%2.2d:%2.2d:%2.2d.%2.2d",(int)hours,(int)minutes,(int)seconds,(int)frames,(int)subframes);
}
-void secondsToTimecodeString(F32 current_time, char *tcstring)
+void secondsToTimecodeString(F32 current_time, std::string& tcstring)
{
microsecondsToTimecodeString((U64)((F64)(SEC_TO_MICROSEC*current_time)), tcstring);
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// LLEventTimer Implementation
-//
-//////////////////////////////////////////////////////////////////////////////
-
-std::list<LLEventTimer*> LLEventTimer::sActiveList;
-
-LLEventTimer::LLEventTimer(F32 period)
-: mEventTimer()
-{
- mPeriod = period;
- sActiveList.push_back(this);
-}
-
-LLEventTimer::~LLEventTimer()
-{
- sActiveList.remove(this);
-}
-
-void LLEventTimer::updateClass()
-{
- std::list<LLEventTimer*> completed_timers;
- for (std::list<LLEventTimer*>::iterator iter = sActiveList.begin(); iter != sActiveList.end(); )
- {
- LLEventTimer* timer = *iter++;
- F32 et = timer->mEventTimer.getElapsedTimeF32();
- if (et > timer->mPeriod) {
- timer->mEventTimer.reset();
- if ( timer->tick() )
- {
- completed_timers.push_back( timer );
- }
- }
- }
-
- if ( completed_timers.size() > 0 )
- {
- for (std::list<LLEventTimer*>::iterator completed_iter = completed_timers.begin();
- completed_iter != completed_timers.end();
- completed_iter++ )
- {
- delete *completed_iter;
- }
- }
-}
-
-