summaryrefslogtreecommitdiff
path: root/indra/llcommon/lltimer.cpp
diff options
context:
space:
mode:
authorDon Kjer <don@lindenlab.com>2008-10-09 18:07:46 +0000
committerDon Kjer <don@lindenlab.com>2008-10-09 18:07:46 +0000
commit4ff16b735f59326514ad92ec38e3261cd996e05c (patch)
tree170416c912dc272e7e171f156494946e05444e55 /indra/llcommon/lltimer.cpp
parentb807e3df990e6fad25cd0bca94d2959dac042b13 (diff)
QAR-907: svn merge -r 98908:98910 svn+ssh://svn/svn/linden/qa/sim-metrics/sim-metrics2-release-merge-98903 into release
Diffstat (limited to 'indra/llcommon/lltimer.cpp')
-rw-r--r--indra/llcommon/lltimer.cpp53
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