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

Comparing SheepShaver/src/timer.cpp (file contents):
Revision 1.11 by asvitkine, 2009-08-01T07:02:41Z vs.
Revision 1.12 by asvitkine, 2009-08-17T20:44:30Z

# Line 29 | Line 29
29   #include <semaphore.h>
30   #endif
31  
32 + #ifdef PRECISE_TIMING_MACH
33 + #include <mach/mach.h>
34 + #endif
35 +
36   #define DEBUG 0
37   #include "debug.h"
38  
# Line 73 | Line 77 | static tm_time_t wakeup_time = wakeup_ti
77   static pthread_mutex_t wakeup_time_lock = PTHREAD_MUTEX_INITIALIZER;
78   static void *timer_func(void *arg);
79   #endif
80 + #ifdef PRECISE_TIMING_MACH
81 + static clock_serv_t system_clock;
82 + static thread_act_t timer_thread;
83 + static bool timer_thread_active = false;
84 + static tm_time_t wakeup_time_max = { 0x7fffffff, 999999999 };
85 + static tm_time_t wakeup_time = wakeup_time_max;
86 + static semaphore_t wakeup_time_sem;
87 + static void *timer_func(void *arg);
88 + #endif
89   #endif
90  
91  
# Line 268 | Line 281 | void TimerInit(void)
281          wakeup_time_sem = create_sem(1, "Wakeup Time");
282          timer_thread = spawn_thread(timer_func, "Time Manager", B_REAL_TIME_PRIORITY, NULL);
283          resume_thread(timer_thread);
284 + #elif PRECISE_TIMING_MACH
285 +        pthread_t pthread;
286 +        
287 +        host_get_clock_service(mach_host_self(), REALTIME_CLOCK, &system_clock);
288 +        semaphore_create(mach_task_self(), &wakeup_time_sem, SYNC_POLICY_FIFO, 1);
289 +
290 +        pthread_create(&pthread, NULL, &timer_func, NULL);
291   #endif
292   #ifdef PRECISE_TIMING_POSIX
293          timer_thread_active = timer_thread_init();
# Line 293 | Line 313 | void TimerExit(void)
313                  wait_for_thread(timer_thread, &l);
314                  delete_sem(wakeup_time_sem);
315   #endif
316 + #ifdef PRECISE_TIMING_MACH
317 +                timer_thread_active = false;
318 +                semaphore_destroy(mach_task_self(), wakeup_time_sem);
319 + #endif
320   #ifdef PRECISE_TIMING_POSIX
321                  timer_thread_kill();
322   #endif
# Line 352 | Line 376 | int16 RmvTime(uint32 tm)
376          while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
377          suspend_thread(timer_thread);
378   #endif
379 + #ifdef PRECISE_TIMING_MACH
380 +        semaphore_wait(wakeup_time_sem);
381 +        thread_suspend(timer_thread);
382 + #endif
383   #if PRECISE_TIMING_POSIX
384          timer_thread_suspend();
385          pthread_mutex_lock(&wakeup_time_lock);
# Line 387 | Line 415 | int16 RmvTime(uint32 tm)
415                  get_thread_info(timer_thread, &info);
416          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
417   #endif
418 + #ifdef PRECISE_TIMING_MACH
419 +        semaphore_signal(wakeup_time_sem);
420 +        thread_abort(timer_thread);
421 +        thread_resume(timer_thread);
422 + #endif
423   #if PRECISE_TIMING_POSIX
424          pthread_mutex_unlock(&wakeup_time_lock);
425          timer_thread_resume();
# Line 461 | Line 494 | int16 PrimeTime(uint32 tm, int32 time)
494          while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
495          suspend_thread(timer_thread);
496   #endif
497 + #ifdef PRECISE_TIMING_MACH
498 +        semaphore_wait(wakeup_time_sem);
499 +        thread_suspend(timer_thread);
500 + #endif
501   #if PRECISE_TIMING_POSIX
502          timer_thread_suspend();
503          pthread_mutex_lock(&wakeup_time_lock);
# Line 483 | Line 520 | int16 PrimeTime(uint32 tm, int32 time)
520                  get_thread_info(timer_thread, &info);
521          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
522   #endif
523 + #ifdef PRECISE_TIMING_MACH
524 +        semaphore_signal(wakeup_time_sem);
525 +        thread_abort(timer_thread);
526 +        thread_resume(timer_thread);
527 + #endif
528   #ifdef PRECISE_TIMING_POSIX
529          pthread_mutex_unlock(&wakeup_time_lock);
530          timer_thread_resume();
# Line 519 | Line 561 | static int32 timer_func(void *arg)
561   }
562   #endif
563  
564 + #ifdef PRECISE_TIMING_MACH
565 + static void *timer_func(void *arg)
566 + {
567 +        timer_thread = mach_thread_self();
568 +        timer_thread_active = true;
569 +        
570 +        while (timer_thread_active) {
571 +                clock_sleep(system_clock, TIME_ABSOLUTE, wakeup_time, NULL);
572 +                semaphore_wait(wakeup_time_sem);
573 +          
574 +                tm_time_t system_time;
575 +                
576 +                timer_current_time(system_time);
577 +                if (timer_cmp_time(wakeup_time, system_time) < 0) {
578 +                        wakeup_time = wakeup_time_max;
579 +                        SetInterruptFlag(INTFLAG_TIMER);
580 +                        TriggerInterrupt();
581 +                }
582 +                semaphore_signal(wakeup_time_sem);
583 +        }
584 + }
585 + #endif
586 +
587   #ifdef PRECISE_TIMING_POSIX
588   static void *timer_func(void *arg)
589   {
590          while (!timer_thread_cancel) {
526
591                  // Wait until time specified by wakeup_time
592                  clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &wakeup_time, NULL);
593  
# Line 583 | Line 647 | void TimerInterrupt(void)
647          while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
648          suspend_thread(timer_thread);
649   #endif
650 + #if PRECISE_TIMING_MACH
651 +        semaphore_wait(wakeup_time_sem);
652 +        thread_suspend(timer_thread);
653 + #endif
654   #if PRECISE_TIMING_POSIX
655          timer_thread_suspend();
656          pthread_mutex_lock(&wakeup_time_lock);
# Line 601 | Line 669 | void TimerInterrupt(void)
669                  get_thread_info(timer_thread, &info);
670          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
671   #endif
672 + #if PRECISE_TIMING_MACH
673 +        semaphore_signal(wakeup_time_sem);
674 +        thread_abort(timer_thread);
675 +        thread_resume(timer_thread);
676 + #endif
677   #if PRECISE_TIMING_POSIX
678          pthread_mutex_unlock(&wakeup_time_lock);
679          timer_thread_resume();

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines