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.16 by gbeauche, 2005-02-21T22:57:03Z vs.
Revision 1.22 by asvitkine, 2009-08-21T17:39:58Z

# Line 1 | Line 1
1   /*
2   *  timer_unix.cpp - Time Manager emulation, Unix specific stuff
3   *
4 < *  Basilisk II (C) 1997-2005 Christian Bauer
4 > *  Basilisk II (C) 1997-2008 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 32 | Line 32
32   #define CLOCK_REALTIME 0
33   #endif
34  
35 + #if defined(__MACH__)
36 + #include <mach/mach.h>
37 + #include <mach/clock.h>
38 +
39 + static clock_serv_t host_clock;
40 + static bool host_clock_inited = false;
41 +
42 + static inline void mach_current_time(tm_time_t &t) {
43 +        if(!host_clock_inited) {
44 +                host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &host_clock);
45 +                host_clock_inited = true;
46 +        }
47 +        
48 +        clock_get_time(host_clock, &t);
49 + }
50 + #endif
51 +
52  
53   /*
54   *  Return microseconds since boot (64 bit)
# Line 40 | Line 57
57   void Microseconds(uint32 &hi, uint32 &lo)
58   {
59          D(bug("Microseconds\n"));
60 < #ifdef HAVE_CLOCK_GETTIME
60 > #if defined(HAVE_CLOCK_GETTIME)
61          struct timespec t;
62          clock_gettime(CLOCK_REALTIME, &t);
63          uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
64 + #elif defined(__MACH__)
65 +        tm_time_t t;
66 +        mach_current_time(t);
67 +        uint64 tl = (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
68   #else
69          struct timeval t;
70          gettimeofday(&t, NULL);
# Line 72 | Line 93 | void timer_current_time(tm_time_t &t)
93   {
94   #ifdef HAVE_CLOCK_GETTIME
95          clock_gettime(CLOCK_REALTIME, &t);
96 + #elif defined(__MACH__)
97 +        mach_current_time(t);
98   #else
99          gettimeofday(&t, NULL);
100   #endif
# Line 84 | Line 107 | void timer_current_time(tm_time_t &t)
107  
108   void timer_add_time(tm_time_t &res, tm_time_t a, tm_time_t b)
109   {
110 < #ifdef HAVE_CLOCK_GETTIME
110 > #if defined(HAVE_CLOCK_GETTIME) || defined(__MACH__)
111          res.tv_sec = a.tv_sec + b.tv_sec;
112          res.tv_nsec = a.tv_nsec + b.tv_nsec;
113          if (res.tv_nsec >= 1000000000) {
# Line 108 | Line 131 | void timer_add_time(tm_time_t &res, tm_t
131  
132   void timer_sub_time(tm_time_t &res, tm_time_t a, tm_time_t b)
133   {
134 < #ifdef HAVE_CLOCK_GETTIME
134 > #if defined(HAVE_CLOCK_GETTIME) || defined(__MACH__)
135          res.tv_sec = a.tv_sec - b.tv_sec;
136          res.tv_nsec = a.tv_nsec - b.tv_nsec;
137          if (res.tv_nsec < 0) {
# Line 132 | Line 155 | void timer_sub_time(tm_time_t &res, tm_t
155  
156   int timer_cmp_time(tm_time_t a, tm_time_t b)
157   {
158 < #ifdef HAVE_CLOCK_GETTIME
158 > #if defined(HAVE_CLOCK_GETTIME) || defined(__MACH__)
159          if (a.tv_sec == b.tv_sec)
160                  return a.tv_nsec - b.tv_nsec;
161          else
# Line 152 | Line 175 | int timer_cmp_time(tm_time_t a, tm_time_
175  
176   void timer_mac2host_time(tm_time_t &res, int32 mactime)
177   {
178 < #ifdef HAVE_CLOCK_GETTIME
178 > #if defined(HAVE_CLOCK_GETTIME) || defined(__MACH__)
179          if (mactime > 0) {
180                  // Time in milliseconds
181                  res.tv_sec = mactime / 1000;
# Line 187 | Line 210 | int32 timer_host2mac_time(tm_time_t host
210          if (hosttime.tv_sec < 0)
211                  return 0;
212          else {
213 < #ifdef HAVE_CLOCK_GETTIME
213 > #if defined(HAVE_CLOCK_GETTIME) || defined(__MACH__)
214                  uint64 t = (uint64)hosttime.tv_sec * 1000000 + hosttime.tv_nsec / 1000;
215   #else
216                  uint64 t = (uint64)hosttime.tv_sec * 1000000 + hosttime.tv_usec;
# Line 210 | Line 233 | uint64 GetTicks_usec(void)
233          struct timespec t;
234          clock_gettime(CLOCK_REALTIME, &t);
235          return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
236 + #elif defined(__MACH__)
237 +        tm_time_t t;
238 +        mach_current_time(t);
239 +        return (uint64)t.tv_sec * 1000000 + t.tv_nsec / 1000;
240   #else
241          struct timeval t;
242          gettimeofday(&t, NULL);
# Line 297 | Line 324 | void Delay_usec(uint32 usec)
324   #endif
325          } while (was_error && (errno == EINTR));
326   }
327 +
328 +
329 + /*
330 + *  Suspend emulator thread, virtual CPU in idle mode
331 + */
332 +
333 + #ifdef HAVE_PTHREADS
334 + #if defined(HAVE_PTHREAD_COND_INIT)
335 + #define IDLE_USES_COND_WAIT 1
336 + static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
337 + static pthread_cond_t idle_cond = PTHREAD_COND_INITIALIZER;
338 + #elif defined(HAVE_SEM_INIT)
339 + #define IDLE_USES_SEMAPHORE 1
340 + #include <semaphore.h>
341 + #ifdef HAVE_SPINLOCKS
342 + static spinlock_t idle_lock = SPIN_LOCK_UNLOCKED;
343 + #define LOCK_IDLE spin_lock(&idle_lock)
344 + #define UNLOCK_IDLE spin_unlock(&idle_lock)
345 + #else
346 + static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER;
347 + #define LOCK_IDLE pthread_mutex_lock(&idle_lock)
348 + #define UNLOCK_IDLE pthread_mutex_unlock(&idle_lock)
349 + #endif
350 + static sem_t idle_sem;
351 + static int idle_sem_ok = -1;
352 + #endif
353 + #endif
354 +
355 + void idle_wait(void)
356 + {
357 + #ifdef IDLE_USES_COND_WAIT
358 +        pthread_mutex_lock(&idle_lock);
359 +        pthread_cond_wait(&idle_cond, &idle_lock);
360 +        pthread_mutex_unlock(&idle_lock);
361 + #else
362 + #ifdef IDLE_USES_SEMAPHORE
363 +        LOCK_IDLE;
364 +        if (idle_sem_ok < 0)
365 +                idle_sem_ok = (sem_init(&idle_sem, 0, 0) == 0);
366 +        if (idle_sem_ok > 0) {
367 +                idle_sem_ok++;
368 +                UNLOCK_IDLE;
369 +                sem_wait(&idle_sem);
370 +                return;
371 +        }
372 +        UNLOCK_IDLE;
373 + #endif
374 +
375 +        // Fallback: sleep 10 ms
376 +        Delay_usec(10000);
377 + #endif
378 + }
379 +
380 +
381 + /*
382 + *  Resume execution of emulator thread, events just arrived
383 + */
384 +
385 + void idle_resume(void)
386 + {
387 + #ifdef IDLE_USES_COND_WAIT
388 +        pthread_cond_signal(&idle_cond);
389 + #else
390 + #ifdef IDLE_USES_SEMAPHORE
391 +        LOCK_IDLE;
392 +        if (idle_sem_ok > 1) {
393 +                idle_sem_ok--;
394 +                UNLOCK_IDLE;
395 +                sem_post(&idle_sem);
396 +                return;
397 +        }
398 +        UNLOCK_IDLE;
399 + #endif
400 + #endif
401 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines