diff options
Diffstat (limited to 'linden/indra/llcommon/lltimer.cpp')
-rw-r--r-- | linden/indra/llcommon/lltimer.cpp | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/linden/indra/llcommon/lltimer.cpp b/linden/indra/llcommon/lltimer.cpp index 967570d..47edfd0 100644 --- a/linden/indra/llcommon/lltimer.cpp +++ b/linden/indra/llcommon/lltimer.cpp | |||
@@ -83,15 +83,20 @@ void ms_sleep(U32 ms) | |||
83 | { | 83 | { |
84 | Sleep(ms); | 84 | Sleep(ms); |
85 | } | 85 | } |
86 | |||
87 | U32 micro_sleep(U64 us, U32 max_yields) | ||
88 | { | ||
89 | // max_yields is unused; just fiddle with it to avoid warnings. | ||
90 | max_yields = 0; | ||
91 | ms_sleep(us / 1000); | ||
92 | return 0; | ||
93 | } | ||
86 | #elif LL_LINUX || LL_SOLARIS || LL_DARWIN | 94 | #elif LL_LINUX || LL_SOLARIS || LL_DARWIN |
87 | void ms_sleep(U32 ms) | 95 | static void _sleep_loop(struct timespec& thiswait) |
88 | { | 96 | { |
89 | long mslong = ms; // tv_nsec is a long | 97 | struct timespec nextwait; |
90 | struct timespec thiswait, nextwait; | ||
91 | bool sleep_more = false; | 98 | bool sleep_more = false; |
92 | 99 | ||
93 | thiswait.tv_sec = ms / 1000; | ||
94 | thiswait.tv_nsec = (mslong % 1000) * 1000000l; | ||
95 | do { | 100 | do { |
96 | int result = nanosleep(&thiswait, &nextwait); | 101 | int result = nanosleep(&thiswait, &nextwait); |
97 | 102 | ||
@@ -127,6 +132,44 @@ void ms_sleep(U32 ms) | |||
127 | } | 132 | } |
128 | } while (sleep_more); | 133 | } while (sleep_more); |
129 | } | 134 | } |
135 | |||
136 | U32 micro_sleep(U64 us, U32 max_yields) | ||
137 | { | ||
138 | U64 start = get_clock_count(); | ||
139 | // This is kernel dependent. Currently, our kernel generates software clock | ||
140 | // interrupts at 250 Hz (every 4,000 microseconds). | ||
141 | const U64 KERNEL_SLEEP_INTERVAL_US = 4000; | ||
142 | |||
143 | S32 num_sleep_intervals = (us - (KERNEL_SLEEP_INTERVAL_US >> 1)) / KERNEL_SLEEP_INTERVAL_US; | ||
144 | if (num_sleep_intervals > 0) | ||
145 | { | ||
146 | U64 sleep_time = (num_sleep_intervals * KERNEL_SLEEP_INTERVAL_US) - (KERNEL_SLEEP_INTERVAL_US >> 1); | ||
147 | struct timespec thiswait; | ||
148 | thiswait.tv_sec = sleep_time / 1000000; | ||
149 | thiswait.tv_nsec = (sleep_time % 1000000) * 1000l; | ||
150 | _sleep_loop(thiswait); | ||
151 | } | ||
152 | |||
153 | U64 current_clock = get_clock_count(); | ||
154 | U32 yields = 0; | ||
155 | while ( (yields < max_yields) | ||
156 | && (current_clock - start < us) ) | ||
157 | { | ||
158 | sched_yield(); | ||
159 | ++yields; | ||
160 | current_clock = get_clock_count(); | ||
161 | } | ||
162 | return yields; | ||
163 | } | ||
164 | |||
165 | void ms_sleep(U32 ms) | ||
166 | { | ||
167 | long mslong = ms; // tv_nsec is a long | ||
168 | struct timespec thiswait; | ||
169 | thiswait.tv_sec = ms / 1000; | ||
170 | thiswait.tv_nsec = (mslong % 1000) * 1000000l; | ||
171 | _sleep_loop(thiswait); | ||
172 | } | ||
130 | #else | 173 | #else |
131 | # error "architecture not supported" | 174 | # error "architecture not supported" |
132 | #endif | 175 | #endif |