ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/timer_unix.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/timer_unix.cpp (file contents):
Revision 1.10 by cebix, 2001-07-06T17:36:08Z vs.
Revision 1.11 by cebix, 2001-07-09T11:22:00Z

# Line 22 | Line 22
22   #include "macos_util.h"
23   #include "timer.h"
24  
25 + #include <errno.h>
26 +
27   #define DEBUG 0
28   #include "debug.h"
29  
# Line 196 | Line 198 | int32 timer_host2mac_time(tm_time_t host
198                          return -t;                      // Time in negative microseconds
199          }
200   }
201 +
202 +
203 + /*
204 + *  Get current value of microsecond timer
205 + */
206 +
207 + uint64 GetTicks_usec(void)
208 + {
209 + #ifdef HAVE_CLOCK_GETTIME
210 +        struct timespec t;
211 +        clock_gettime(CLOCK_REALTIME, &t);
212 +        return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
213 + #else
214 +        struct timeval t;
215 +        gettimeofday(&t, NULL);
216 +        return (uint64)t.tv_sec * 1000000 + t.tv_usec;
217 + #endif
218 + }
219 +
220 +
221 + /*
222 + *  Delay by specified number of microseconds (<1 second)
223 + *  (adapted from SDL_Delay() source; this function is designed to provide
224 + *  the highest accuracy possible)
225 + */
226 +
227 + #if defined(linux)
228 + // Linux select() changes its timeout parameter upon return to contain
229 + // the remaining time. Most other unixen leave it unchanged or undefined.
230 + #define SELECT_SETS_REMAINING
231 + #elif defined(__FreeBSD__) || defined(__sun__)
232 + #define USE_NANOSLEEP
233 + #elif defined(HAVE_PTHREADS) && defined(sgi)
234 + // SGI pthreads has a bug when using pthreads+signals+nanosleep,
235 + // so instead of using nanosleep, wait on a CV which is never signalled.
236 + #define USE_COND_TIMEDWAIT
237 + #endif
238 +
239 + void Delay_usec(uint32 usec)
240 + {
241 +        int was_error;
242 +
243 + #if defined(USE_NANOSLEEP)
244 +        struct timespec elapsed, tv;
245 + #elif defined(USE_COND_TIMEDWAIT)
246 +        // Use a local mutex and cv, so threads remain independent
247 +        pthread_cond_t delay_cond = PTHREAD_COND_INITIALIZER;
248 +        pthread_mutex_t delay_mutex = PTHREAD_MUTEX_INITIALIZER;
249 +        struct timespec elapsed;
250 +        uint64 future;
251 + #else
252 +        struct timeval tv;
253 + #ifndef SELECT_SETS_REMAINING
254 +        uint64 then, now, elapsed;
255 + #endif
256 + #endif
257 +
258 +        // Set the timeout interval - Linux only needs to do this once
259 + #if defined(SELECT_SETS_REMAINING)
260 +    tv.tv_sec = 0;
261 +    tv.tv_usec = usec;
262 + #elif defined(USE_NANOSLEEP)
263 +    elapsed.tv_sec = 0;
264 +    elapsed.tv_nsec = usec * 1000;
265 + #elif defined(USE_COND_TIMEDWAIT)
266 +        future = GetTicks_usec() + usec;
267 +        elapsed.tv_sec = future / 1000000;
268 +        elapsed.tv_nsec = (future % 1000000) * 1000;
269 + #else
270 +    then = GetTicks_usec();
271 + #endif
272 +
273 +        do {
274 +                errno = 0;
275 + #if defined(USE_NANOSLEEP)
276 +                tv.tv_sec = elapsed.tv_sec;
277 +                tv.tv_nsec = elapsed.tv_nsec;
278 +                was_error = nanosleep(&tv, &elapsed);
279 + #elif defined(USE_COND_TIMEDWAIT)
280 +                was_error = pthread_mutex_lock(&delay_mutex);
281 +                was_error = pthread_cond_timedwait(&delay_cond, &delay_mutex, &elapsed);
282 +                was_error = pthread_mutex_unlock(&delay_mutex);
283 + #else
284 + #ifndef SELECT_SETS_REMAINING
285 +                // Calculate the time interval left (in case of interrupt)
286 +                now = GetTicks_usec();
287 +                elapsed = now - then;
288 +                then = now;
289 +                if (elapsed >= usec)
290 +                        break;
291 +                usec -= elapsed;
292 +                tv.tv_sec = 0;
293 +                tv.tv_usec = usec;
294 + #endif
295 +                was_error = select(0, NULL, NULL, NULL, &tv);
296 + #endif
297 +        } while (was_error && (errno == EINTR));
298 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines