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.2 by cebix, 1999-10-14T16:05:18Z vs.
Revision 1.11 by cebix, 2001-07-09T11:22:00Z

# Line 1 | Line 1
1   /*
2   *  timer_unix.cpp - Time Manager emulation, Unix specific stuff
3   *
4 < *  Basilisk II (C) 1997-1999 Christian Bauer
4 > *  Basilisk II (C) 1997-2001 Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 19 | Line 19
19   */
20  
21   #include "sysdeps.h"
22 + #include "macos_util.h"
23   #include "timer.h"
24  
25 + #include <errno.h>
26 +
27   #define DEBUG 0
28   #include "debug.h"
29  
30 + // For NetBSD with broken pthreads headers
31 + #ifndef CLOCK_REALTIME
32 + #define CLOCK_REALTIME 0
33 + #endif
34 +
35  
36   /*
37   *  Return microseconds since boot (64 bit)
# Line 50 | Line 58 | void Microseconds(uint32 &hi, uint32 &lo
58   *  Return local date/time in Mac format (seconds since 1.1.1904)
59   */
60  
53 const uint32 TIME_OFFSET = 0x7c25b080;  // Offset Mac->Unix time in seconds
54
61   uint32 TimerDateTime(void)
62   {
63 <        time_t uct_now = time(NULL);
58 <        long tz = timezone;
59 <        time_t local_now = uct_now - tz;
60 <        if (daylight)
61 <                local_now += 3600;
62 <        return (uint32)local_now + TIME_OFFSET;
63 >        return TimeToMacTime(time(NULL));
64   }
65  
66  
# Line 197 | 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