From ba4e7b989b6c20a49da0eeb450bd2f945b3eefc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20N=C3=A6sbye=20Christensen?= Date: Thu, 8 Feb 2024 02:51:51 +0100 Subject: llcommon: BOOL (int) to real bool/LSTATUS --- indra/llcommon/lltimer.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'indra/llcommon/lltimer.cpp') diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 1a99ac2886..42c4911ff1 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -96,7 +96,7 @@ U32 micro_sleep(U64 us, U32 max_yields) LARGE_INTEGER ft; ft.QuadPart = -static_cast(us * 10); // '-' using relative time - HANDLE timer = CreateWaitableTimer(NULL, TRUE, NULL); + HANDLE timer = CreateWaitableTimer(NULL, true, NULL); SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); WaitForSingleObject(timer, INFINITE); CloseHandle(timer); @@ -324,7 +324,7 @@ LLTimer::LLTimer() get_timer_info().update(); } - mStarted = TRUE; + mStarted = true; reset(); } @@ -441,31 +441,31 @@ F32SecondsImplicit LLTimer::getRemainingTimeF32() const } -BOOL LLTimer::checkExpirationAndReset(F32 expiration) +bool LLTimer::checkExpirationAndReset(F32 expiration) { U64 cur_ticks = get_clock_count(); if (cur_ticks < mExpirationTicks) { - return FALSE; + return false; } mExpirationTicks = cur_ticks + (U64)((F32)(expiration * get_timer_info().mClockFrequency)); - return TRUE; + return true; } -BOOL LLTimer::hasExpired() const +bool LLTimer::hasExpired() const { return (get_clock_count() >= mExpirationTicks) - ? TRUE : FALSE; + ? true : false; } /////////////////////////////////////////////////////////////////////////////// -BOOL LLTimer::knownBadTimer() +bool LLTimer::knownBadTimer() { - BOOL failed = FALSE; + bool failed = false; #if LL_WINDOWS WCHAR bad_pci_list[][10] = {L"1039:0530", @@ -507,7 +507,7 @@ BOOL LLTimer::knownBadTimer() if (!wcscmp(pci_id, bad_pci_list[check])) { // LL_WARNS() << "unreliable PCI chipset found!! " << pci_id << endl; - failed = TRUE; + failed = true; break; } } @@ -533,7 +533,7 @@ time_t time_corrected() // Is the current computer (in its current time zone) // observing daylight savings time? -BOOL is_daylight_savings() +bool is_daylight_savings() { time_t now = time(NULL); @@ -547,7 +547,7 @@ BOOL is_daylight_savings() } -struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time) +struct tm* utc_to_pacific_time(time_t utc_time, bool pacific_daylight_time) { S32Hours pacific_offset_hours; if (pacific_daylight_time) -- cgit v1.2.3 From f9473e8afcb624cc1b101195bf15943ec372b56f Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Mon, 6 May 2024 16:52:34 +0200 Subject: secondlife/viewer#1333 BOOL to bool conversion leftovers: ternaries --- indra/llcommon/lltimer.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'indra/llcommon/lltimer.cpp') diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 42c4911ff1..b1ddfc952c 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -424,7 +424,7 @@ F32SecondsImplicit LLTimer::getElapsedTimeAndResetF32() /////////////////////////////////////////////////////////////////////////////// -void LLTimer::setTimerExpirySec(F32SecondsImplicit expiration) +void LLTimer::setTimerExpirySec(F32SecondsImplicit expiration) { mExpirationTicks = get_clock_count() + (U64)((F32)(expiration * get_timer_info().mClockFrequency.value())); @@ -441,7 +441,7 @@ F32SecondsImplicit LLTimer::getRemainingTimeF32() const } -bool LLTimer::checkExpirationAndReset(F32 expiration) +bool LLTimer::checkExpirationAndReset(F32 expiration) { U64 cur_ticks = get_clock_count(); if (cur_ticks < mExpirationTicks) @@ -455,10 +455,9 @@ bool LLTimer::checkExpirationAndReset(F32 expiration) } -bool LLTimer::hasExpired() const +bool LLTimer::hasExpired() const { - return (get_clock_count() >= mExpirationTicks) - ? true : false; + return get_clock_count() >= mExpirationTicks; } /////////////////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 Mon Sep 17 00:00:00 2001 From: Ansariel Date: Wed, 22 May 2024 21:25:21 +0200 Subject: Fix line endlings --- indra/llcommon/lltimer.cpp | 1216 ++++++++++++++++++++++---------------------- 1 file changed, 608 insertions(+), 608 deletions(-) (limited to 'indra/llcommon/lltimer.cpp') diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 8a8451b927..a3e871661c 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -1,608 +1,608 @@ -/** - * @file lltimer.cpp - * @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$ - */ - -#include "linden_common.h" - -#include "lltimer.h" - -#include "u64.h" - -#include -#include - -#if LL_WINDOWS -# include "llwin32headerslean.h" -#elif LL_LINUX || LL_DARWIN -# include -# include -#else -# error "architecture not supported" -#endif - -// -// Locally used constants -// -const U64 SEC_TO_MICROSEC_U64 = 1000000; - -//--------------------------------------------------------------------------- -// Globals and statics -//--------------------------------------------------------------------------- - -S32 gUTCOffset = 0; // viewer's offset from server UTC, in seconds -LLTimer* LLTimer::sTimer = NULL; - - -// -// Forward declarations -// - - -//--------------------------------------------------------------------------- -// Implementation -//--------------------------------------------------------------------------- - -#if LL_WINDOWS - - -#if 0 -void ms_sleep(U32 ms) -{ - LL_PROFILE_ZONE_SCOPED; - using TimePoint = std::chrono::steady_clock::time_point; - auto resume_time = TimePoint::clock::now() + std::chrono::milliseconds(ms); - while (TimePoint::clock::now() < resume_time) - { - std::this_thread::yield(); //note: don't use LLThread::yield here to avoid yielding for too long - } -} - -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)); - return 0; -} - -#else - -U32 micro_sleep(U64 us, U32 max_yields) -{ - LL_PROFILE_ZONE_SCOPED -#if 0 - LARGE_INTEGER ft; - ft.QuadPart = -static_cast(us * 10); // '-' using relative time - - HANDLE timer = CreateWaitableTimer(NULL, true, NULL); - SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); - WaitForSingleObject(timer, INFINITE); - CloseHandle(timer); -#else - Sleep(us / 1000); -#endif - - return 0; -} - -void ms_sleep(U32 ms) -{ - LL_PROFILE_ZONE_SCOPED - micro_sleep(ms * 1000, 0); -} - -#endif - -#elif LL_LINUX || LL_DARWIN -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); -} - -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 S64 KERNEL_SLEEP_INTERVAL_US = 4000; - - // Use signed arithmetic to discover whether a sleep is even necessary. If - // either 'us' or KERNEL_SLEEP_INTERVAL_US is unsigned, the compiler - // promotes the difference to unsigned. If 'us' is less than half - // KERNEL_SLEEP_INTERVAL_US, the unsigned difference will be hugely - // positive, resulting in a crazy long wait. - auto num_sleep_intervals = (S64(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 - -// -// CPU clock/other clock frequency and count functions -// - -#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 - - // 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; -} -#endif // LL_WINDOWS - - -#if LL_LINUX || LL_DARWIN -// Both Linux and Mac use gettimeofday for accurate time -F64 calc_clock_frequency() -{ - 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; -} -#endif - - -TimerInfo::TimerInfo() -: mClockFrequency(0.0), - mTotalTimeClockCount(0), - mLastTotalTimeClockCount(0) -{} - -void TimerInfo::update() -{ - 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 -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; - -#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. - - 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; - } - - // Return the total clock tick count in microseconds. - U64Microseconds time(get_timer_info().mTotalTimeClockCount*get_timer_info().mClocksToMicroseconds); - return time; -} - - -/////////////////////////////////////////////////////////////////////////////// - -LLTimer::LLTimer() -{ - if (!get_timer_info().mClockFrequency) - { - get_timer_info().update(); - } - - mStarted = true; - reset(); -} - -LLTimer::~LLTimer() -{} - -// static -void LLTimer::initClass() -{ - if (!sTimer) sTimer = new LLTimer; -} - -// static -void LLTimer::cleanupClass() -{ - delete sTimer; sTimer = NULL; -} - -// static -U64MicrosecondsImplicit LLTimer::getTotalTime() -{ - // simply call into the implementation function. - U64MicrosecondsImplicit total_time = totalTime(); - return total_time; -} - -// static -F64SecondsImplicit LLTimer::getTotalSeconds() -{ - return F64Microseconds(U64_to_F64(getTotalTime())); -} - -void LLTimer::reset() -{ - mLastClockCount = get_clock_count(); - mExpirationTicks = 0; -} - -/////////////////////////////////////////////////////////////////////////////// - -U64 LLTimer::getCurrentClockCount() -{ - return get_clock_count(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void LLTimer::setLastClockCount(U64 current_count) -{ - mLastClockCount = current_count; -} - -/////////////////////////////////////////////////////////////////////////////// - -static -U64 getElapsedTimeAndUpdate(U64& lastClockCount) -{ - 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; - } - - lastClockCount = current_clock_count; - - return result; -} - - -F64SecondsImplicit LLTimer::getElapsedTimeF64() const -{ - U64 last = mLastClockCount; - return (F64)getElapsedTimeAndUpdate(last) * get_timer_info().mClockFrequencyInv; -} - -F32SecondsImplicit LLTimer::getElapsedTimeF32() const -{ - return (F32)getElapsedTimeF64(); -} - -F64SecondsImplicit LLTimer::getElapsedTimeAndResetF64() -{ - return (F64)getElapsedTimeAndUpdate(mLastClockCount) * get_timer_info().mClockFrequencyInv; -} - -F32SecondsImplicit LLTimer::getElapsedTimeAndResetF32() -{ - return (F32)getElapsedTimeAndResetF64(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void LLTimer::setTimerExpirySec(F32SecondsImplicit expiration) -{ - 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); -} - - -bool LLTimer::checkExpirationAndReset(F32 expiration) -{ - U64 cur_ticks = get_clock_count(); - if (cur_ticks < mExpirationTicks) - { - return false; - } - - mExpirationTicks = cur_ticks - + (U64)((F32)(expiration * get_timer_info().mClockFrequency)); - return true; -} - - -bool LLTimer::hasExpired() const -{ - return get_clock_count() >= mExpirationTicks; -} - -/////////////////////////////////////////////////////////////////////////////// - -bool LLTimer::knownBadTimer() -{ - 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; - } - } -#endif - return(failed); -} - -/////////////////////////////////////////////////////////////////////////////// -// -// NON-MEMBER FUNCTIONS -// -/////////////////////////////////////////////////////////////////////////////// - -time_t time_corrected() -{ - return time(NULL) + gUTCOffset; -} - - -// Is the current computer (in its current time zone) -// observing daylight savings time? -bool is_daylight_savings() -{ - time_t now = time(NULL); - - // 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); -} - - -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); - } - - // 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); - - /* - // 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; -} - - -void microsecondsToTimecodeString(U64MicrosecondsImplicit current_time, std::string& tcstring) -{ - 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; - - 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); -} - - +/** + * @file lltimer.cpp + * @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$ + */ + +#include "linden_common.h" + +#include "lltimer.h" + +#include "u64.h" + +#include +#include + +#if LL_WINDOWS +# include "llwin32headerslean.h" +#elif LL_LINUX || LL_DARWIN +# include +# include +#else +# error "architecture not supported" +#endif + +// +// Locally used constants +// +const U64 SEC_TO_MICROSEC_U64 = 1000000; + +//--------------------------------------------------------------------------- +// Globals and statics +//--------------------------------------------------------------------------- + +S32 gUTCOffset = 0; // viewer's offset from server UTC, in seconds +LLTimer* LLTimer::sTimer = NULL; + + +// +// Forward declarations +// + + +//--------------------------------------------------------------------------- +// Implementation +//--------------------------------------------------------------------------- + +#if LL_WINDOWS + + +#if 0 +void ms_sleep(U32 ms) +{ + LL_PROFILE_ZONE_SCOPED; + using TimePoint = std::chrono::steady_clock::time_point; + auto resume_time = TimePoint::clock::now() + std::chrono::milliseconds(ms); + while (TimePoint::clock::now() < resume_time) + { + std::this_thread::yield(); //note: don't use LLThread::yield here to avoid yielding for too long + } +} + +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)); + return 0; +} + +#else + +U32 micro_sleep(U64 us, U32 max_yields) +{ + LL_PROFILE_ZONE_SCOPED +#if 0 + LARGE_INTEGER ft; + ft.QuadPart = -static_cast(us * 10); // '-' using relative time + + HANDLE timer = CreateWaitableTimer(NULL, true, NULL); + SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); +#else + Sleep(us / 1000); +#endif + + return 0; +} + +void ms_sleep(U32 ms) +{ + LL_PROFILE_ZONE_SCOPED + micro_sleep(ms * 1000, 0); +} + +#endif + +#elif LL_LINUX || LL_DARWIN +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); +} + +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 S64 KERNEL_SLEEP_INTERVAL_US = 4000; + + // Use signed arithmetic to discover whether a sleep is even necessary. If + // either 'us' or KERNEL_SLEEP_INTERVAL_US is unsigned, the compiler + // promotes the difference to unsigned. If 'us' is less than half + // KERNEL_SLEEP_INTERVAL_US, the unsigned difference will be hugely + // positive, resulting in a crazy long wait. + auto num_sleep_intervals = (S64(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 + +// +// CPU clock/other clock frequency and count functions +// + +#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 + + // 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; +} +#endif // LL_WINDOWS + + +#if LL_LINUX || LL_DARWIN +// Both Linux and Mac use gettimeofday for accurate time +F64 calc_clock_frequency() +{ + 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; +} +#endif + + +TimerInfo::TimerInfo() +: mClockFrequency(0.0), + mTotalTimeClockCount(0), + mLastTotalTimeClockCount(0) +{} + +void TimerInfo::update() +{ + 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 +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; + +#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. + + 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; + } + + // Return the total clock tick count in microseconds. + U64Microseconds time(get_timer_info().mTotalTimeClockCount*get_timer_info().mClocksToMicroseconds); + return time; +} + + +/////////////////////////////////////////////////////////////////////////////// + +LLTimer::LLTimer() +{ + if (!get_timer_info().mClockFrequency) + { + get_timer_info().update(); + } + + mStarted = true; + reset(); +} + +LLTimer::~LLTimer() +{} + +// static +void LLTimer::initClass() +{ + if (!sTimer) sTimer = new LLTimer; +} + +// static +void LLTimer::cleanupClass() +{ + delete sTimer; sTimer = NULL; +} + +// static +U64MicrosecondsImplicit LLTimer::getTotalTime() +{ + // simply call into the implementation function. + U64MicrosecondsImplicit total_time = totalTime(); + return total_time; +} + +// static +F64SecondsImplicit LLTimer::getTotalSeconds() +{ + return F64Microseconds(U64_to_F64(getTotalTime())); +} + +void LLTimer::reset() +{ + mLastClockCount = get_clock_count(); + mExpirationTicks = 0; +} + +/////////////////////////////////////////////////////////////////////////////// + +U64 LLTimer::getCurrentClockCount() +{ + return get_clock_count(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void LLTimer::setLastClockCount(U64 current_count) +{ + mLastClockCount = current_count; +} + +/////////////////////////////////////////////////////////////////////////////// + +static +U64 getElapsedTimeAndUpdate(U64& lastClockCount) +{ + 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; + } + + lastClockCount = current_clock_count; + + return result; +} + + +F64SecondsImplicit LLTimer::getElapsedTimeF64() const +{ + U64 last = mLastClockCount; + return (F64)getElapsedTimeAndUpdate(last) * get_timer_info().mClockFrequencyInv; +} + +F32SecondsImplicit LLTimer::getElapsedTimeF32() const +{ + return (F32)getElapsedTimeF64(); +} + +F64SecondsImplicit LLTimer::getElapsedTimeAndResetF64() +{ + return (F64)getElapsedTimeAndUpdate(mLastClockCount) * get_timer_info().mClockFrequencyInv; +} + +F32SecondsImplicit LLTimer::getElapsedTimeAndResetF32() +{ + return (F32)getElapsedTimeAndResetF64(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void LLTimer::setTimerExpirySec(F32SecondsImplicit expiration) +{ + 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); +} + + +bool LLTimer::checkExpirationAndReset(F32 expiration) +{ + U64 cur_ticks = get_clock_count(); + if (cur_ticks < mExpirationTicks) + { + return false; + } + + mExpirationTicks = cur_ticks + + (U64)((F32)(expiration * get_timer_info().mClockFrequency)); + return true; +} + + +bool LLTimer::hasExpired() const +{ + return get_clock_count() >= mExpirationTicks; +} + +/////////////////////////////////////////////////////////////////////////////// + +bool LLTimer::knownBadTimer() +{ + 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; + } + } +#endif + return(failed); +} + +/////////////////////////////////////////////////////////////////////////////// +// +// NON-MEMBER FUNCTIONS +// +/////////////////////////////////////////////////////////////////////////////// + +time_t time_corrected() +{ + return time(NULL) + gUTCOffset; +} + + +// Is the current computer (in its current time zone) +// observing daylight savings time? +bool is_daylight_savings() +{ + time_t now = time(NULL); + + // 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); +} + + +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); + } + + // 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); + + /* + // 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; +} + + +void microsecondsToTimecodeString(U64MicrosecondsImplicit current_time, std::string& tcstring) +{ + 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; + + 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); +} + + -- cgit v1.2.3 From 9fdca96f8bd2211a99fe88e57b70cbecefa20b6d Mon Sep 17 00:00:00 2001 From: Ansariel Date: Mon, 8 Jul 2024 20:27:14 +0200 Subject: Re-enable compiler warnings C4244 and C4396 except for lltracerecording.h and llunittype.h for now --- indra/llcommon/lltimer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llcommon/lltimer.cpp') diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index a3e871661c..e5c0970d35 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -101,7 +101,7 @@ U32 micro_sleep(U64 us, U32 max_yields) WaitForSingleObject(timer, INFINITE); CloseHandle(timer); #else - Sleep(us / 1000); + Sleep((DWORD)(us / 1000)); #endif return 0; -- cgit v1.2.3 From 2a7030992faa12c362d3eb9365080efd8265e15f Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 9 Jul 2024 17:53:43 -0400 Subject: Update tracy profiler to 0.10 (#1946) --- indra/llcommon/lltimer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llcommon/lltimer.cpp') diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index e5c0970d35..28d6e4e4cc 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -91,7 +91,7 @@ U32 micro_sleep(U64 us, U32 max_yields) U32 micro_sleep(U64 us, U32 max_yields) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED; #if 0 LARGE_INTEGER ft; ft.QuadPart = -static_cast(us * 10); // '-' using relative time @@ -109,7 +109,7 @@ U32 micro_sleep(U64 us, U32 max_yields) void ms_sleep(U32 ms) { - LL_PROFILE_ZONE_SCOPED + LL_PROFILE_ZONE_SCOPED; micro_sleep(ms * 1000, 0); } -- cgit v1.2.3