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.11 by asvitkine, 2009-08-01T07:02:41Z

# 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 18 | Line 18
18   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  
21 /*
22 * TODO: Prime(0)
23 */
24
21   #include "sysdeps.h"
22   #include "timer.h"
23   #include "macos_util.h"
# Line 74 | Line 70 | static bool timer_thread_active = false;
70   static volatile bool timer_thread_cancel = false;
71   static tm_time_t wakeup_time_max = { 0x7fffffff, 999999999 };
72   static tm_time_t wakeup_time = wakeup_time_max;
73 < static sem_t wakeup_time_sem;
73 > static pthread_mutex_t wakeup_time_lock = PTHREAD_MUTEX_INITIALIZER;
74   static void *timer_func(void *arg);
75   #endif
76   #endif
# Line 185 | Line 181 | static void sigresume_handler(int sig)
181   static bool timer_thread_init(void)
182   {
183          // Install suspend signal handler
184 <        sigfillset(&sigsuspend_action.sa_mask);
184 >        sigemptyset(&sigsuspend_action.sa_mask);
185 >        sigaddset(&sigsuspend_action.sa_mask, SIGRESUME);
186          sigsuspend_action.sa_handler = sigsuspend_handler;
187          sigsuspend_action.sa_flags = SA_RESTART;
188   #ifdef HAVE_SIGNAL_SA_RESTORER
# Line 195 | Line 192 | static bool timer_thread_init(void)
192                  return false;
193  
194          // Install resume signal handler
195 <        sigfillset(&sigresume_action.sa_mask);
195 >        sigemptyset(&sigresume_action.sa_mask);
196          sigresume_action.sa_handler = sigresume_handler;
197          sigresume_action.sa_flags = SA_RESTART;
198   #ifdef HAVE_SIGNAL_SA_RESTORER
# Line 273 | Line 270 | void TimerInit(void)
270          resume_thread(timer_thread);
271   #endif
272   #ifdef PRECISE_TIMING_POSIX
276        sem_init(&wakeup_time_sem, 0, 1);
273          timer_thread_active = timer_thread_init();
274   #endif
275   #endif
# Line 299 | Line 295 | void TimerExit(void)
295   #endif
296   #ifdef PRECISE_TIMING_POSIX
297                  timer_thread_kill();
302                sem_destroy(&wakeup_time_sem);
298   #endif
299          }
300   #endif
# Line 358 | Line 353 | int16 RmvTime(uint32 tm)
353          suspend_thread(timer_thread);
354   #endif
355   #if PRECISE_TIMING_POSIX
361        sem_wait(&wakeup_time_sem);
356          timer_thread_suspend();
357 +        pthread_mutex_lock(&wakeup_time_lock);
358   #endif
359          if (ReadMacInt16(tm + qType) & 0x8000) {
360  
# Line 393 | Line 388 | int16 RmvTime(uint32 tm)
388          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
389   #endif
390   #if PRECISE_TIMING_POSIX
391 <        sem_post(&wakeup_time_sem);
391 >        pthread_mutex_unlock(&wakeup_time_lock);
392          timer_thread_resume();
393          assert(suspend_count == 0);
394   #endif
# Line 429 | Line 424 | int16 PrimeTime(uint32 tm, int32 time)
424                  // Yes, tmWakeUp set?
425                  if (ReadMacInt32(tm + tmWakeUp)) {
426  
427 <                        //!! PrimeTime(0) means continue previous delay
428 <                        // (save wakeup time in RmvTime?)
427 >                        // PrimeTime(0) can either mean (a) "the task runs as soon as interrupts are enabled"
428 >                        // or (b) "continue previous delay" if an expired task was stopped via RmvTime() and
429 >                        // then re-installed using InsXTime(). Since tmWakeUp was set, this is case (b).
430 >                        // The remaining time was saved in tmCount by RmvTime().
431                          if (time == 0) {
432 <                                printf("FATAL: Unsupported PrimeTime(0)\n");
436 <                                return 0;
432 >                                timer_mac2host_time(delay, ReadMacInt16(tm + tmCount));
433                          }
434  
435                          // Yes, calculate wakeup time relative to last scheduled time
# Line 466 | Line 462 | int16 PrimeTime(uint32 tm, int32 time)
462          suspend_thread(timer_thread);
463   #endif
464   #if PRECISE_TIMING_POSIX
469        sem_wait(&wakeup_time_sem);
465          timer_thread_suspend();
466 +        pthread_mutex_lock(&wakeup_time_lock);
467   #endif
468          WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000);
469          enqueue_tm(tm);
# Line 488 | Line 484 | int16 PrimeTime(uint32 tm, int32 time)
484          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
485   #endif
486   #ifdef PRECISE_TIMING_POSIX
487 <        sem_post(&wakeup_time_sem);
487 >        pthread_mutex_unlock(&wakeup_time_lock);
488          timer_thread_resume();
489          assert(suspend_count == 0);
490   #endif
# Line 531 | Line 527 | static void *timer_func(void *arg)
527                  // Wait until time specified by wakeup_time
528                  clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &wakeup_time, NULL);
529  
534                sem_wait(&wakeup_time_sem);
530                  tm_time_t system_time;
531                  timer_current_time(system_time);
532                  if (timer_cmp_time(wakeup_time, system_time) < 0) {
533  
534                          // Timer expired, trigger interrupt
535 +                        pthread_mutex_lock(&wakeup_time_lock);
536                          wakeup_time = wakeup_time_max;
537 +                        pthread_mutex_unlock(&wakeup_time_lock);
538                          SetInterruptFlag(INTFLAG_TIMER);
539                          TriggerInterrupt();
540                  }
544                sem_post(&wakeup_time_sem);
541          }
542          return NULL;
543   }
# Line 588 | Line 584 | void TimerInterrupt(void)
584          suspend_thread(timer_thread);
585   #endif
586   #if PRECISE_TIMING_POSIX
591        sem_wait(&wakeup_time_sem);
587          timer_thread_suspend();
588 +        pthread_mutex_lock(&wakeup_time_lock);
589   #endif
590          wakeup_time = wakeup_time_max;
591          for (int j=0; j<NUM_DESCS; j++) {
# Line 606 | Line 602 | void TimerInterrupt(void)
602          } while (info.state == B_THREAD_SUSPENDED);     // Sometimes, resume_thread() doesn't work (BeOS bug?)
603   #endif
604   #if PRECISE_TIMING_POSIX
605 <        sem_post(&wakeup_time_sem);
605 >        pthread_mutex_unlock(&wakeup_time_lock);
606          timer_thread_resume();
607          assert(suspend_count == 0);
608   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines