diff options
Diffstat (limited to 'indra/llcommon/lltimer.cpp')
-rw-r--r-- | indra/llcommon/lltimer.cpp | 144 |
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; - } - } -} - - |