home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / libc / posix / signal / itimer.c next >
Encoding:
C/C++ Source or Header  |  1995-07-15  |  2.5 KB  |  102 lines

  1. /* Copyright (C) 1995 Charles Sandmann (sandmann@clio.rice.edu)
  2.    setitimer implmentation - used for profiling and alarm
  3.    BUGS: ONLY ONE AT A TIME, first pass code
  4.    This software may be freely distributed, no warranty. */
  5.  
  6. #include <libc/stubs.h>
  7. #include <sys/time.h>
  8. #include <errno.h>
  9. #include <dpmi.h>
  10. #include <signal.h>
  11.  
  12. static struct itimerval real, prof;
  13.  
  14. /* not right, should compute from current tic count.  Do later */
  15. int getitimer(int which, struct itimerval *value)
  16. {
  17.   if(which == ITIMER_REAL) {
  18.     *value = real;
  19.     return 0;
  20.   } else if(which == ITIMER_PROF) {
  21.     *value = prof;
  22.     return 0;
  23.   }
  24.   errno = EINVAL;
  25.   return -1;
  26. }
  27.  
  28. extern unsigned __djgpp_timer_countdown;
  29. extern __dpmi_paddr __djgpp_old_timer;
  30. extern int __djgpp_timer_hdlr;
  31. static char timer_on = 0;
  32. static int sigtype = SIGALRM;
  33. static int reload = 0;
  34.  
  35. static void stop_timer(void)
  36. {
  37.   if(!timer_on)
  38.     return;
  39.   __djgpp_timer_countdown = -1;
  40.   __dpmi_set_protected_mode_interrupt_vector(8, &__djgpp_old_timer);
  41.   timer_on = 0;
  42.   signal(SIGTIMR, SIG_DFL);
  43. }
  44.  
  45. static void timer_action(int signum)
  46. {
  47.   if(reload)
  48.     __djgpp_timer_countdown = reload;
  49.   else
  50.     stop_timer();
  51.   raise(sigtype);
  52. }
  53.  
  54. static void start_timer(void)
  55. {
  56.   __dpmi_paddr int8;
  57.  
  58.   if(timer_on)
  59.     return;
  60.   timer_on = 1;
  61.   signal(SIGTIMR, timer_action);
  62.   __dpmi_get_protected_mode_interrupt_vector(8, &__djgpp_old_timer);
  63.   asm("movw %%cs,%0" : "=g" (int8.selector) );
  64.   int8.offset32 = (unsigned) &__djgpp_timer_hdlr;
  65.   __dpmi_set_protected_mode_interrupt_vector(8, &int8);
  66. }
  67.  
  68. /* Note, this should have a scheduler to handle both, do later.  Currently
  69.    can't have both at same time */
  70.  
  71. int setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
  72. {
  73.   if(ovalue)
  74.     if(getitimer(which,ovalue))
  75.       return -1;    /* errno already set */
  76.  
  77.   if((value->it_value.tv_sec | value->it_value.tv_usec) == 0) {
  78.     stop_timer();
  79.     return 0;
  80.   }
  81.   
  82.   if(which == ITIMER_REAL) {
  83.     sigtype = SIGALRM;
  84.   } else if(which == ITIMER_PROF) {
  85.     sigtype = SIGPROF;
  86.   } else {
  87.     errno = EINVAL;
  88.     return -1;
  89.   }
  90.   
  91.   __djgpp_timer_countdown = value->it_value.tv_sec * 18;
  92.   __djgpp_timer_countdown += value->it_value.tv_sec / 5;
  93.   __djgpp_timer_countdown += (value->it_value.tv_usec + 54944) / 54955;
  94.   
  95.   reload = value->it_interval.tv_sec * 18;
  96.   reload += value->it_interval.tv_sec / 5;
  97.   reload += (value->it_interval.tv_usec + 54944) / 54955;
  98.   
  99.   start_timer();
  100.   return 0;
  101. }
  102.