diff options
Diffstat (limited to 'indra/llcommon/lltimer.cpp')
-rw-r--r-- | indra/llcommon/lltimer.cpp | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 7570420d2c..2c34608064 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -83,15 +83,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 +132,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 |