diff options
author | Erik Kundiman <erik@megapahit.org> | 2024-05-16 13:52:40 +0800 |
---|---|---|
committer | Erik Kundiman <erik@megapahit.org> | 2024-05-16 13:52:40 +0800 |
commit | 6d51e91895a7f2435c46a876410ccc6c63fe8c82 (patch) | |
tree | f2b48ebd99cb414227bf365f47665b8d4baa752b /indra/llcommon/lltimer.cpp | |
parent | d1b5917bb9c92e4e47eba19b43781e4d1328b1ca (diff) | |
parent | 094dcc07f8c1d90ae723dbe60eddacb90a09eae8 (diff) |
Merge tag '7.1.7-release'
source for viewer 7.1.7.8974243247
Diffstat (limited to 'indra/llcommon/lltimer.cpp')
-rw-r--r-- | indra/llcommon/lltimer.cpp | 524 |
1 files changed, 262 insertions, 262 deletions
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index e96927e9c1..1f644d0a1e 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -1,25 +1,25 @@ -/** +/** * @file lltimer.cpp - * @brief Cross-platform objects for doing timing + * @brief Cross-platform objects for doing timing * * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code * 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. - * + * * 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. - * + * * 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$ */ @@ -34,12 +34,12 @@ #include <thread> #if LL_WINDOWS -# include "llwin32headerslean.h" +# include "llwin32headerslean.h" #elif LL_LINUX || LL_DARWIN || LL_FREEBSD # include <errno.h> -# include <sys/time.h> -#else -# error "architecture not supported" +# include <sys/time.h> +#else +# error "architecture not supported" #endif // @@ -83,7 +83,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((U32)(us / 1000)); + ms_sleep((U32)(us / 1000)); return 0; } @@ -118,43 +118,43 @@ void ms_sleep(U32 ms) #elif LL_LINUX || LL_DARWIN || LL_FREEBSD static void _sleep_loop(struct timespec& thiswait) { - struct timespec nextwait; - bool sleep_more = false; - - do { - int result = nanosleep(&thiswait, &nextwait); - - // check if sleep was interrupted by a signal; unslept - // remainder was written back into 't' and we just nanosleep - // again. - sleep_more = (result == -1 && EINTR == errno); - - if (sleep_more) - { - if ( nextwait.tv_sec > thiswait.tv_sec || - (nextwait.tv_sec == thiswait.tv_sec && - nextwait.tv_nsec >= thiswait.tv_nsec) ) - { - // if the remaining time isn't actually going - // down then we're being shafted by low clock - // resolution - manually massage the sleep time - // downward. - if (nextwait.tv_nsec > 1000000) { - // lose 1ms - nextwait.tv_nsec -= 1000000; - } else { - if (nextwait.tv_sec == 0) { - // already so close to finished - sleep_more = false; - } else { - // lose up to 1ms - nextwait.tv_nsec = 0; - } - } - } - thiswait = nextwait; - } - } while (sleep_more); + struct timespec nextwait; + bool sleep_more = false; + + do { + int result = nanosleep(&thiswait, &nextwait); + + // check if sleep was interrupted by a signal; unslept + // remainder was written back into 't' and we just nanosleep + // again. + sleep_more = (result == -1 && EINTR == errno); + + if (sleep_more) + { + if ( nextwait.tv_sec > thiswait.tv_sec || + (nextwait.tv_sec == thiswait.tv_sec && + nextwait.tv_nsec >= thiswait.tv_nsec) ) + { + // if the remaining time isn't actually going + // down then we're being shafted by low clock + // resolution - manually massage the sleep time + // downward. + if (nextwait.tv_nsec > 1000000) { + // lose 1ms + nextwait.tv_nsec -= 1000000; + } else { + if (nextwait.tv_sec == 0) { + // already so close to finished + sleep_more = false; + } else { + // lose up to 1ms + nextwait.tv_nsec = 0; + } + } + } + thiswait = nextwait; + } + } while (sleep_more); } U32 micro_sleep(U64 us, U32 max_yields) @@ -193,10 +193,10 @@ U32 micro_sleep(U64 us, U32 max_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; + 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 @@ -210,25 +210,25 @@ void ms_sleep(U32 ms) #if LL_WINDOWS U64 get_clock_count() { - static bool firstTime = true; - static U64 offset; - // ensures that callers to this function never have to deal with wrap + static bool firstTime = true; + static U64 offset; + // ensures that callers to this function never have to deal with wrap - // QueryPerformanceCounter implementation - LARGE_INTEGER clock_count; - QueryPerformanceCounter(&clock_count); - if (firstTime) { - offset = clock_count.QuadPart; - firstTime = false; - } - return clock_count.QuadPart - offset; + // QueryPerformanceCounter implementation + LARGE_INTEGER clock_count; + QueryPerformanceCounter(&clock_count); + if (firstTime) { + offset = clock_count.QuadPart; + firstTime = false; + } + return clock_count.QuadPart - offset; } F64 calc_clock_frequency() { - __int64 freq; - QueryPerformanceFrequency((LARGE_INTEGER *) &freq); - return (F64)freq; + __int64 freq; + QueryPerformanceFrequency((LARGE_INTEGER *) &freq); + return (F64)freq; } #endif // LL_WINDOWS @@ -237,81 +237,81 @@ F64 calc_clock_frequency() // Both Linux and Mac use gettimeofday for accurate time F64 calc_clock_frequency() { - return 1000000.0; // microseconds, so 1 MHz. + return 1000000.0; // microseconds, so 1 MHz. } U64 get_clock_count() { - // Linux clocks are in microseconds - struct timeval tv; - gettimeofday(&tv, NULL); - return tv.tv_sec*SEC_TO_MICROSEC_U64 + tv.tv_usec; + // Linux clocks are in microseconds + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec*SEC_TO_MICROSEC_U64 + tv.tv_usec; } #endif TimerInfo::TimerInfo() -: mClockFrequency(0.0), - mTotalTimeClockCount(0), - mLastTotalTimeClockCount(0) +: mClockFrequency(0.0), + mTotalTimeClockCount(0), + mLastTotalTimeClockCount(0) {} void TimerInfo::update() { - mClockFrequency = calc_clock_frequency(); - mClockFrequencyInv = 1.0/mClockFrequency; - mClocksToMicroseconds = mClockFrequencyInv; + mClockFrequency = calc_clock_frequency(); + mClockFrequencyInv = 1.0/mClockFrequency; + mClocksToMicroseconds = mClockFrequencyInv; } TimerInfo& get_timer_info() { - static TimerInfo sTimerInfo; - return sTimerInfo; + static TimerInfo sTimerInfo; + return sTimerInfo; } /////////////////////////////////////////////////////////////////////////////// -// returns a U64 number that represents the number of +// returns a U64 number that represents the number of // microseconds since the Unix epoch - Jan 1, 1970 U64MicrosecondsImplicit totalTime() { - U64 current_clock_count = get_clock_count(); - if (!get_timer_info().mTotalTimeClockCount || get_timer_info().mClocksToMicroseconds.value() == 0) - { - get_timer_info().update(); - get_timer_info().mTotalTimeClockCount = current_clock_count; + U64 current_clock_count = get_clock_count(); + if (!get_timer_info().mTotalTimeClockCount || get_timer_info().mClocksToMicroseconds.value() == 0) + { + get_timer_info().update(); + get_timer_info().mTotalTimeClockCount = current_clock_count; #if LL_WINDOWS - // 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. + // 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. - get_timer_info().mTotalTimeClockCount = (U64)(time(NULL) * get_timer_info().mClockFrequency); + get_timer_info().mTotalTimeClockCount = (U64)(time(NULL) * get_timer_info().mClockFrequency); #endif - // Update the last clock count - get_timer_info().mLastTotalTimeClockCount = current_clock_count; - } - else - { - if (current_clock_count >= get_timer_info().mLastTotalTimeClockCount) - { - // No wrapping, we're all okay. - get_timer_info().mTotalTimeClockCount += current_clock_count - get_timer_info().mLastTotalTimeClockCount; - } - else - { - // We've wrapped. Compensate correctly - get_timer_info().mTotalTimeClockCount += (0xFFFFFFFFFFFFFFFFULL - get_timer_info().mLastTotalTimeClockCount) + current_clock_count; - } - - // Update the last clock count - get_timer_info().mLastTotalTimeClockCount = current_clock_count; - } + // Update the last clock count + get_timer_info().mLastTotalTimeClockCount = current_clock_count; + } + else + { + if (current_clock_count >= get_timer_info().mLastTotalTimeClockCount) + { + // No wrapping, we're all okay. + get_timer_info().mTotalTimeClockCount += current_clock_count - get_timer_info().mLastTotalTimeClockCount; + } + else + { + // We've wrapped. Compensate correctly + get_timer_info().mTotalTimeClockCount += (0xFFFFFFFFFFFFFFFFULL - get_timer_info().mLastTotalTimeClockCount) + current_clock_count; + } + + // Update the last clock count + get_timer_info().mLastTotalTimeClockCount = current_clock_count; + } - // Return the total clock tick count in microseconds. - U64Microseconds time(get_timer_info().mTotalTimeClockCount*get_timer_info().mClocksToMicroseconds); - return time; + // Return the total clock tick count in microseconds. + U64Microseconds time(get_timer_info().mTotalTimeClockCount*get_timer_info().mClocksToMicroseconds); + return time; } @@ -319,13 +319,13 @@ U64MicrosecondsImplicit totalTime() LLTimer::LLTimer() { - if (!get_timer_info().mClockFrequency) - { - get_timer_info().update(); - } + if (!get_timer_info().mClockFrequency) + { + get_timer_info().update(); + } - mStarted = TRUE; - reset(); + mStarted = TRUE; + reset(); } LLTimer::~LLTimer() @@ -334,47 +334,47 @@ LLTimer::~LLTimer() // static void LLTimer::initClass() { - if (!sTimer) sTimer = new LLTimer; + if (!sTimer) sTimer = new LLTimer; } // static void LLTimer::cleanupClass() { - delete sTimer; sTimer = NULL; + delete sTimer; sTimer = NULL; } // static U64MicrosecondsImplicit LLTimer::getTotalTime() { - // simply call into the implementation function. - U64MicrosecondsImplicit total_time = totalTime(); - return total_time; -} + // simply call into the implementation function. + U64MicrosecondsImplicit total_time = totalTime(); + return total_time; +} // static F64SecondsImplicit LLTimer::getTotalSeconds() { - return F64Microseconds(U64_to_F64(getTotalTime())); + return F64Microseconds(U64_to_F64(getTotalTime())); } void LLTimer::reset() { - mLastClockCount = get_clock_count(); - mExpirationTicks = 0; + mLastClockCount = get_clock_count(); + mExpirationTicks = 0; } /////////////////////////////////////////////////////////////////////////////// U64 LLTimer::getCurrentClockCount() { - return get_clock_count(); + return get_clock_count(); } /////////////////////////////////////////////////////////////////////////////// void LLTimer::setLastClockCount(U64 current_count) { - mLastClockCount = current_count; + mLastClockCount = current_count; } /////////////////////////////////////////////////////////////////////////////// @@ -382,152 +382,152 @@ void LLTimer::setLastClockCount(U64 current_count) static U64 getElapsedTimeAndUpdate(U64& lastClockCount) { - U64 current_clock_count = get_clock_count(); - U64 result; + U64 current_clock_count = get_clock_count(); + U64 result; - if (current_clock_count >= lastClockCount) - { - result = current_clock_count - lastClockCount; - } - else - { - // time has gone backward - result = 0; - } + if (current_clock_count >= lastClockCount) + { + result = current_clock_count - lastClockCount; + } + else + { + // time has gone backward + result = 0; + } - lastClockCount = current_clock_count; + lastClockCount = current_clock_count; - return result; + return result; } F64SecondsImplicit LLTimer::getElapsedTimeF64() const { - U64 last = mLastClockCount; - return (F64)getElapsedTimeAndUpdate(last) * get_timer_info().mClockFrequencyInv; + U64 last = mLastClockCount; + return (F64)getElapsedTimeAndUpdate(last) * get_timer_info().mClockFrequencyInv; } F32SecondsImplicit LLTimer::getElapsedTimeF32() const { - return (F32)getElapsedTimeF64(); + return (F32)getElapsedTimeF64(); } F64SecondsImplicit LLTimer::getElapsedTimeAndResetF64() { - return (F64)getElapsedTimeAndUpdate(mLastClockCount) * get_timer_info().mClockFrequencyInv; + return (F64)getElapsedTimeAndUpdate(mLastClockCount) * get_timer_info().mClockFrequencyInv; } F32SecondsImplicit LLTimer::getElapsedTimeAndResetF32() { - return (F32)getElapsedTimeAndResetF64(); + return (F32)getElapsedTimeAndResetF64(); } /////////////////////////////////////////////////////////////////////////////// void LLTimer::setTimerExpirySec(F32SecondsImplicit expiration) { - mExpirationTicks = get_clock_count() - + (U64)((F32)(expiration * get_timer_info().mClockFrequency.value())); + mExpirationTicks = get_clock_count() + + (U64)((F32)(expiration * get_timer_info().mClockFrequency.value())); } F32SecondsImplicit LLTimer::getRemainingTimeF32() const { - U64 cur_ticks = get_clock_count(); - if (cur_ticks > mExpirationTicks) - { - return 0.0f; - } - return F32((mExpirationTicks - cur_ticks) * get_timer_info().mClockFrequencyInv); + U64 cur_ticks = get_clock_count(); + if (cur_ticks > mExpirationTicks) + { + return 0.0f; + } + return F32((mExpirationTicks - cur_ticks) * get_timer_info().mClockFrequencyInv); } BOOL LLTimer::checkExpirationAndReset(F32 expiration) { - U64 cur_ticks = get_clock_count(); - if (cur_ticks < mExpirationTicks) - { - return FALSE; - } + U64 cur_ticks = get_clock_count(); + if (cur_ticks < mExpirationTicks) + { + return FALSE; + } - mExpirationTicks = cur_ticks - + (U64)((F32)(expiration * get_timer_info().mClockFrequency)); - return TRUE; + mExpirationTicks = cur_ticks + + (U64)((F32)(expiration * get_timer_info().mClockFrequency)); + return TRUE; } BOOL LLTimer::hasExpired() const { - return (get_clock_count() >= mExpirationTicks) - ? TRUE : FALSE; + return (get_clock_count() >= mExpirationTicks) + ? TRUE : FALSE; } /////////////////////////////////////////////////////////////////////////////// BOOL LLTimer::knownBadTimer() { - BOOL failed = FALSE; + BOOL failed = FALSE; #if LL_WINDOWS - WCHAR bad_pci_list[][10] = {L"1039:0530", - L"1039:0620", - L"10B9:0533", - L"10B9:1533", - L"1106:0596", - L"1106:0686", - L"1166:004F", - L"1166:0050", - L"8086:7110", - L"\0" - }; - - HKEY hKey = NULL; - LONG nResult = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"SYSTEM\\CurrentControlSet\\Enum\\PCI", 0, - KEY_EXECUTE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey); - - WCHAR name[1024]; - DWORD name_len = 1024; - FILETIME scrap; - - S32 key_num = 0; - WCHAR pci_id[10]; - - wcscpy(pci_id, L"0000:0000"); /*Flawfinder: ignore*/ - - while (nResult == ERROR_SUCCESS) - { - nResult = ::RegEnumKeyEx(hKey, key_num++, name, &name_len, NULL, NULL, NULL, &scrap); - - if (nResult == ERROR_SUCCESS) - { - memcpy(&pci_id[0],&name[4],4); /* Flawfinder: ignore */ - memcpy(&pci_id[5],&name[13],4); /* Flawfinder: ignore */ - - for (S32 check = 0; bad_pci_list[check][0]; check++) - { - if (!wcscmp(pci_id, bad_pci_list[check])) - { -// LL_WARNS() << "unreliable PCI chipset found!! " << pci_id << endl; - failed = TRUE; - break; - } - } -// llinfo << "PCI chipset found: " << pci_id << endl; - name_len = 1024; - } - } + WCHAR bad_pci_list[][10] = {L"1039:0530", + L"1039:0620", + L"10B9:0533", + L"10B9:1533", + L"1106:0596", + L"1106:0686", + L"1166:004F", + L"1166:0050", + L"8086:7110", + L"\0" + }; + + HKEY hKey = NULL; + LONG nResult = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,L"SYSTEM\\CurrentControlSet\\Enum\\PCI", 0, + KEY_EXECUTE | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey); + + WCHAR name[1024]; + DWORD name_len = 1024; + FILETIME scrap; + + S32 key_num = 0; + WCHAR pci_id[10]; + + wcscpy(pci_id, L"0000:0000"); /*Flawfinder: ignore*/ + + while (nResult == ERROR_SUCCESS) + { + nResult = ::RegEnumKeyEx(hKey, key_num++, name, &name_len, NULL, NULL, NULL, &scrap); + + if (nResult == ERROR_SUCCESS) + { + memcpy(&pci_id[0],&name[4],4); /* Flawfinder: ignore */ + memcpy(&pci_id[5],&name[13],4); /* Flawfinder: ignore */ + + for (S32 check = 0; bad_pci_list[check][0]; check++) + { + if (!wcscmp(pci_id, bad_pci_list[check])) + { +// LL_WARNS() << "unreliable PCI chipset found!! " << pci_id << endl; + failed = TRUE; + break; + } + } +// llinfo << "PCI chipset found: " << pci_id << endl; + name_len = 1024; + } + } #endif - return(failed); + return(failed); } /////////////////////////////////////////////////////////////////////////////// -// +// // NON-MEMBER FUNCTIONS // /////////////////////////////////////////////////////////////////////////////// time_t time_corrected() { - return time(NULL) + gUTCOffset; + return time(NULL) + gUTCOffset; } @@ -535,75 +535,75 @@ time_t time_corrected() // observing daylight savings time? BOOL is_daylight_savings() { - time_t now = time(NULL); + time_t now = time(NULL); - // Internal buffer to local server time - struct tm* internal_time = localtime(&now); + // Internal buffer to local server time + struct tm* internal_time = localtime(&now); - // tm_isdst > 0 => daylight savings - // tm_isdst = 0 => not daylight savings - // tm_isdst < 0 => can't tell - return (internal_time->tm_isdst > 0); + // tm_isdst > 0 => daylight savings + // tm_isdst = 0 => not daylight savings + // tm_isdst < 0 => can't tell + return (internal_time->tm_isdst > 0); } struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time) { - S32Hours pacific_offset_hours; - if (pacific_daylight_time) - { - pacific_offset_hours = S32Hours(7); - } - else - { - pacific_offset_hours = S32Hours(8); - } + S32Hours pacific_offset_hours; + if (pacific_daylight_time) + { + pacific_offset_hours = S32Hours(7); + } + else + { + 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 -= S32SecondsImplicit(pacific_offset_hours); - // 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 -= S32SecondsImplicit(pacific_offset_hours); - - // Internal buffer to PST/PDT (see above) - struct tm* internal_time = gmtime(&utc_time); + // Internal buffer to PST/PDT (see above) + struct tm* internal_time = gmtime(&utc_time); - /* - // Don't do this, this won't correctly tell you if daylight savings is active in CA or not. - if (pacific_daylight_time) - { - internal_time->tm_isdst = 1; - } - */ + /* + // Don't do this, this won't correctly tell you if daylight savings is active in CA or not. + if (pacific_daylight_time) + { + internal_time->tm_isdst = 1; + } + */ - return internal_time; + return internal_time; } void microsecondsToTimecodeString(U64MicrosecondsImplicit current_time, std::string& tcstring) { - U64 hours; - U64 minutes; - U64 seconds; - U64 frames; - U64 subframes; + U64 hours; + U64 minutes; + U64 seconds; + U64 frames; + U64 subframes; - hours = current_time / (U64)3600000000ul; - minutes = current_time / (U64)60000000; - minutes %= 60; - seconds = current_time / (U64)1000000; - seconds %= 60; - frames = current_time / (U64)41667; - frames %= 24; - subframes = current_time / (U64)42; - subframes %= 100; + hours = current_time / (U64)3600000000ul; + minutes = current_time / (U64)60000000; + minutes %= 60; + seconds = current_time / (U64)1000000; + seconds %= 60; + frames = current_time / (U64)41667; + frames %= 24; + subframes = current_time / (U64)42; + subframes %= 100; - tcstring = llformat("%3.3d:%2.2d:%2.2d:%2.2d.%2.2d",(int)hours,(int)minutes,(int)seconds,(int)frames,(int)subframes); + tcstring = llformat("%3.3d:%2.2d:%2.2d:%2.2d.%2.2d",(int)hours,(int)minutes,(int)seconds,(int)frames,(int)subframes); } void secondsToTimecodeString(F32SecondsImplicit current_time, std::string& tcstring) { - microsecondsToTimecodeString(current_time, tcstring); + microsecondsToTimecodeString(current_time, tcstring); } |