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.5 by gbeauche, 2005-03-15T20:46:50Z vs.
Revision 1.9 by asvitkine, 2009-07-31T19:41:50Z

# Line 1 | Line 1
1   /*
2   *  timer.cpp - Time Manager emulation
3   *
4 < *  SheepShaver (C) 1997-2005 Christian Bauer and Marc Hellwig
4 > *  SheepShaver (C) 1997-2008 Christian Bauer and Marc Hellwig
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 74 | Line 74 | static bool timer_thread_active = false;
74   static volatile bool timer_thread_cancel = false;
75   static tm_time_t wakeup_time_max = { 0x7fffffff, 999999999 };
76   static tm_time_t wakeup_time = wakeup_time_max;
77 < static sem_t wakeup_time_sem;
77 > static pthread_mutex_t wakeup_time_lock = PTHREAD_MUTEX_INITIALIZER;
78   static void *timer_func(void *arg);
79   #endif
80   #endif
# Line 185 | Line 185 | static void sigresume_handler(int sig)
185   static bool timer_thread_init(void)
186   {
187          // Install suspend signal handler
188 <        sigfillset(&sigsuspend_action.sa_mask);
188 >        sigemptyset(&sigsuspend_action.sa_mask);
189 >        sigaddset(&sigsuspend_action.sa_mask, SIGRESUME);
190          sigsuspend_action.sa_handler = sigsuspend_handler;
191          sigsuspend_action.sa_flags = SA_RESTART;
192   #ifdef HAVE_SIGNAL_SA_RESTORER
# Line 195 | Line 196 | static bool timer_thread_init(void)
196                  return false;
197  
198          // Install resume signal handler
199 <        sigfillset(&sigresume_action.sa_mask);
199 >        sigemptyset(&sigresume_action.sa_mask);
200          sigresume_action.sa_handler = sigresume_handler;
201          sigresume_action.sa_flags = SA_RESTART;
202   #ifdef HAVE_SIGNAL_SA_RESTORER
# Line 273 | Line 274 | void TimerInit(void)
274          resume_thread(timer_thread);
275   #endif
276   #ifdef PRECISE_TIMING_POSIX
276        sem_init(&wakeup_time_sem, 0, 1);
277          timer_thread_active = timer_thread_init();
278   #endif
279   #endif
# Line 299 | Line 299 | void TimerExit(void)
299   #endif
300   #ifdef PRECISE_TIMING_POSIX
301                  timer_thread_kill();
302                sem_destroy(&wakeup_time_sem);
302   #endif
303          }
304   #endif
# Line 358 | Line 357 | int16 RmvTime(uint32 tm)
357          suspend_thread(timer_thread);
358   #endif
359   #if PRECISE_TIMING_POSIX
361        sem_wait(&wakeup_time_sem);
360          timer_thread_suspend();
361 +        pthread_mutex_lock(&wakeup_time_lock);
362   #endif
363          if (ReadMacInt16(tm + qType) & 0x8000) {
364  
# Line 393 | Line 392 | int16 RmvTime(uint32 tm)
392          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
393   #endif
394   #if PRECISE_TIMING_POSIX
395 <        sem_post(&wakeup_time_sem);
395 >        pthread_mutex_unlock(&wakeup_time_lock);
396          timer_thread_resume();
397          assert(suspend_count == 0);
398   #endif
# Line 429 | Line 428 | int16 PrimeTime(uint32 tm, int32 time)
428                  // Yes, tmWakeUp set?
429                  if (ReadMacInt32(tm + tmWakeUp)) {
430  
431 +                        // PrimeTime(0) can either mean (a) "the task runs as soon as interrupts are enabled"
432 +                        // or (b) "continue previous delay" if an expired task was stopped via RmvTime() and
433 +                        // then re-installed using InsXTime(). This currently only handles (a).
434 +                        //
435 +                        // API reference: http://developer.apple.com/documentation/mac/Processes/Processes-68.html
436 +
437 + #if 0
438                          //!! PrimeTime(0) means continue previous delay
439                          // (save wakeup time in RmvTime?)
440                          if (time == 0) {
441                                  printf("FATAL: Unsupported PrimeTime(0)\n");
442                                  return 0;
443                          }
444 + #endif
445  
446                          // Yes, calculate wakeup time relative to last scheduled time
447                          tm_time_t wakeup;
# Line 466 | Line 473 | int16 PrimeTime(uint32 tm, int32 time)
473          suspend_thread(timer_thread);
474   #endif
475   #if PRECISE_TIMING_POSIX
469        sem_wait(&wakeup_time_sem);
476          timer_thread_suspend();
477 +        pthread_mutex_lock(&wakeup_time_lock);
478   #endif
479          WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000);
480          enqueue_tm(tm);
# Line 488 | Line 495 | int16 PrimeTime(uint32 tm, int32 time)
495          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
496   #endif
497   #ifdef PRECISE_TIMING_POSIX
498 <        sem_post(&wakeup_time_sem);
498 >        pthread_mutex_unlock(&wakeup_time_lock);
499          timer_thread_resume();
500          assert(suspend_count == 0);
501   #endif
# Line 531 | Line 538 | static void *timer_func(void *arg)
538                  // Wait until time specified by wakeup_time
539                  clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &wakeup_time, NULL);
540  
534                sem_wait(&wakeup_time_sem);
541                  tm_time_t system_time;
542                  timer_current_time(system_time);
543                  if (timer_cmp_time(wakeup_time, system_time) < 0) {
544  
545                          // Timer expired, trigger interrupt
546 +                        pthread_mutex_lock(&wakeup_time_lock);
547                          wakeup_time = wakeup_time_max;
548 +                        pthread_mutex_unlock(&wakeup_time_lock);
549                          SetInterruptFlag(INTFLAG_TIMER);
550                          TriggerInterrupt();
551                  }
544                sem_post(&wakeup_time_sem);
552          }
553          return NULL;
554   }
# Line 588 | Line 595 | void TimerInterrupt(void)
595          suspend_thread(timer_thread);
596   #endif
597   #if PRECISE_TIMING_POSIX
591        sem_wait(&wakeup_time_sem);
598          timer_thread_suspend();
599 +        pthread_mutex_lock(&wakeup_time_lock);
600   #endif
601          wakeup_time = wakeup_time_max;
602          for (int j=0; j<NUM_DESCS; j++) {
# Line 606 | Line 613 | void TimerInterrupt(void)
613          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
614   #endif
615   #if PRECISE_TIMING_POSIX
616 <        sem_post(&wakeup_time_sem);
616 >        pthread_mutex_unlock(&wakeup_time_lock);
617          timer_thread_resume();
618          assert(suspend_count == 0);
619   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines