Diff for /qemu/qemu-timer.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2018/04/24 18:24:03 version 1.1.1.2, 2018/04/24 18:33:57
Line 64  int64_t qemu_icount_bias; Line 64  int64_t qemu_icount_bias;
 static QEMUTimer *icount_rt_timer;  static QEMUTimer *icount_rt_timer;
 static QEMUTimer *icount_vm_timer;  static QEMUTimer *icount_vm_timer;
   
   
 /***********************************************************/  
 /* real time host monotonic timer */  
   
   
 static int64_t get_clock_realtime(void)  
 {  
     struct timeval tv;  
   
     gettimeofday(&tv, NULL);  
     return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);  
 }  
   
 #ifdef WIN32  
   
 static int64_t clock_freq;  
   
 static void init_get_clock(void)  
 {  
     LARGE_INTEGER freq;  
     int ret;  
     ret = QueryPerformanceFrequency(&freq);  
     if (ret == 0) {  
         fprintf(stderr, "Could not calibrate ticks\n");  
         exit(1);  
     }  
     clock_freq = freq.QuadPart;  
 }  
   
 static int64_t get_clock(void)  
 {  
     LARGE_INTEGER ti;  
     QueryPerformanceCounter(&ti);  
     return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);  
 }  
   
 #else  
   
 static int use_rt_clock;  
   
 static void init_get_clock(void)  
 {  
     use_rt_clock = 0;  
 #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \  
     || defined(__DragonFly__) || defined(__FreeBSD_kernel__)  
     {  
         struct timespec ts;  
         if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {  
             use_rt_clock = 1;  
         }  
     }  
 #endif  
 }  
   
 static int64_t get_clock(void)  
 {  
 #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \  
         || defined(__DragonFly__) || defined(__FreeBSD_kernel__)  
     if (use_rt_clock) {  
         struct timespec ts;  
         clock_gettime(CLOCK_MONOTONIC, &ts);  
         return ts.tv_sec * 1000000000LL + ts.tv_nsec;  
     } else  
 #endif  
     {  
         /* XXX: using gettimeofday leads to problems if the date  
            changes, so it should be avoided. */  
         return get_clock_realtime();  
     }  
 }  
 #endif  
   
 /***********************************************************/  /***********************************************************/
 /* guest cycle counter */  /* guest cycle counter */
   
Line 182  static int64_t cpu_get_clock(void) Line 110  static int64_t cpu_get_clock(void)
     }      }
 }  }
   
 #ifndef CONFIG_IOTHREAD  
 static int64_t qemu_icount_delta(void)  static int64_t qemu_icount_delta(void)
 {  {
     if (!use_icount) {      if (!use_icount) {
Line 196  static int64_t qemu_icount_delta(void) Line 123  static int64_t qemu_icount_delta(void)
         return cpu_get_icount() - cpu_get_clock();          return cpu_get_icount() - cpu_get_clock();
     }      }
 }  }
 #endif  
   
 /* enable cpu_get_ticks() */  /* enable cpu_get_ticks() */
 void cpu_enable_ticks(void)  void cpu_enable_ticks(void)
Line 271  static void qemu_rearm_alarm_timer(struc Line 197  static void qemu_rearm_alarm_timer(struc
     t->rearm(t);      t->rearm(t);
 }  }
   
 /* TODO: MIN_TIMER_REARM_US should be optimized */  /* TODO: MIN_TIMER_REARM_NS should be optimized */
 #define MIN_TIMER_REARM_US 250  #define MIN_TIMER_REARM_NS 250000
   
 #ifdef _WIN32  #ifdef _WIN32
   
Line 614  int64_t qemu_get_clock_ns(QEMUClock *clo Line 540  int64_t qemu_get_clock_ns(QEMUClock *clo
   
 void init_clocks(void)  void init_clocks(void)
 {  {
     init_get_clock();  
     rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);      rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
     vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);      vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
     host_clock = qemu_new_clock(QEMU_CLOCK_HOST);      host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
Line 710  void qemu_run_all_timers(void) Line 635  void qemu_run_all_timers(void)
     qemu_run_timers(host_clock);      qemu_run_timers(host_clock);
 }  }
   
   static int64_t qemu_next_alarm_deadline(void);
   
 #ifdef _WIN32  #ifdef _WIN32
 static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,  static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
                                         DWORD_PTR dwUser, DWORD_PTR dw1,                                          DWORD_PTR dwUser, DWORD_PTR dw1,
Line 752  static void host_alarm_handler(int host_ Line 679  static void host_alarm_handler(int host_
     }      }
 #endif  #endif
     if (alarm_has_dynticks(t) ||      if (alarm_has_dynticks(t) ||
         (!use_icount &&          qemu_next_alarm_deadline () <= 0) {
             qemu_timer_expired(active_timers[QEMU_CLOCK_VIRTUAL],  
                                qemu_get_clock(vm_clock))) ||  
         qemu_timer_expired(active_timers[QEMU_CLOCK_REALTIME],  
                            qemu_get_clock(rt_clock)) ||  
         qemu_timer_expired(active_timers[QEMU_CLOCK_HOST],  
                            qemu_get_clock(host_clock))) {  
   
         t->expired = alarm_has_dynticks(t);          t->expired = alarm_has_dynticks(t);
         t->pending = 1;          t->pending = 1;
         qemu_notify_event();          qemu_notify_event();
Line 773  int64_t qemu_next_deadline(void) Line 693  int64_t qemu_next_deadline(void)
   
     if (active_timers[QEMU_CLOCK_VIRTUAL]) {      if (active_timers[QEMU_CLOCK_VIRTUAL]) {
         delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -          delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
                      qemu_get_clock(vm_clock);                       qemu_get_clock_ns(vm_clock);
     }      }
     if (active_timers[QEMU_CLOCK_HOST]) {      if (active_timers[QEMU_CLOCK_HOST]) {
         int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -          int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
                  qemu_get_clock(host_clock);                   qemu_get_clock_ns(host_clock);
         if (hdelta < delta)          if (hdelta < delta)
             delta = hdelta;              delta = hdelta;
     }      }
Line 788  int64_t qemu_next_deadline(void) Line 708  int64_t qemu_next_deadline(void)
     return delta;      return delta;
 }  }
   
 #ifndef _WIN32  static int64_t qemu_next_alarm_deadline(void)
   
 #if defined(__linux__)  
   
 #define RTC_FREQ 1024  
   
 static uint64_t qemu_next_deadline_dyntick(void)  
 {  {
     int64_t delta;      int64_t delta;
     int64_t rtdelta;      int64_t rtdelta;
   
     if (use_icount)      if (!use_icount && active_timers[QEMU_CLOCK_VIRTUAL]) {
           delta = active_timers[QEMU_CLOCK_VIRTUAL]->expire_time -
                        qemu_get_clock(vm_clock);
       } else {
         delta = INT32_MAX;          delta = INT32_MAX;
     else      }
         delta = (qemu_next_deadline() + 999) / 1000;      if (active_timers[QEMU_CLOCK_HOST]) {
           int64_t hdelta = active_timers[QEMU_CLOCK_HOST]->expire_time -
                    qemu_get_clock_ns(host_clock);
           if (hdelta < delta)
               delta = hdelta;
       }
     if (active_timers[QEMU_CLOCK_REALTIME]) {      if (active_timers[QEMU_CLOCK_REALTIME]) {
         rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time -          rtdelta = (active_timers[QEMU_CLOCK_REALTIME]->expire_time * 1000000 -
                  qemu_get_clock(rt_clock))*1000;                   qemu_get_clock_ns(rt_clock));
         if (rtdelta < delta)          if (rtdelta < delta)
             delta = rtdelta;              delta = rtdelta;
     }      }
   
     if (delta < MIN_TIMER_REARM_US)  
         delta = MIN_TIMER_REARM_US;  
   
     return delta;      return delta;
 }  }
   
   #if defined(__linux__)
   
   #define RTC_FREQ 1024
   
 static void enable_sigio_timer(int fd)  static void enable_sigio_timer(int fd)
 {  {
     struct sigaction act;      struct sigaction act;
Line 962  static void dynticks_rearm_timer(struct  Line 884  static void dynticks_rearm_timer(struct 
 {  {
     timer_t host_timer = (timer_t)(long)t->priv;      timer_t host_timer = (timer_t)(long)t->priv;
     struct itimerspec timeout;      struct itimerspec timeout;
     int64_t nearest_delta_us = INT64_MAX;      int64_t nearest_delta_ns = INT64_MAX;
     int64_t current_us;      int64_t current_ns;
   
     assert(alarm_has_dynticks(t));      assert(alarm_has_dynticks(t));
     if (!active_timers[QEMU_CLOCK_REALTIME] &&      if (!active_timers[QEMU_CLOCK_REALTIME] &&
Line 971  static void dynticks_rearm_timer(struct  Line 893  static void dynticks_rearm_timer(struct 
         !active_timers[QEMU_CLOCK_HOST])          !active_timers[QEMU_CLOCK_HOST])
         return;          return;
   
     nearest_delta_us = qemu_next_deadline_dyntick();      nearest_delta_ns = qemu_next_alarm_deadline();
       if (nearest_delta_ns < MIN_TIMER_REARM_NS)
           nearest_delta_ns = MIN_TIMER_REARM_NS;
   
     /* check whether a timer is already running */      /* check whether a timer is already running */
     if (timer_gettime(host_timer, &timeout)) {      if (timer_gettime(host_timer, &timeout)) {
Line 979  static void dynticks_rearm_timer(struct  Line 903  static void dynticks_rearm_timer(struct 
         fprintf(stderr, "Internal timer error: aborting\n");          fprintf(stderr, "Internal timer error: aborting\n");
         exit(1);          exit(1);
     }      }
     current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;      current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
     if (current_us && current_us <= nearest_delta_us)      if (current_ns && current_ns <= nearest_delta_ns)
         return;          return;
   
     timeout.it_interval.tv_sec = 0;      timeout.it_interval.tv_sec = 0;
     timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */      timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
     timeout.it_value.tv_sec =  nearest_delta_us / 1000000;      timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
     timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;      timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
     if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {      if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
         perror("settime");          perror("settime");
         fprintf(stderr, "Internal timer error: aborting\n");          fprintf(stderr, "Internal timer error: aborting\n");
Line 996  static void dynticks_rearm_timer(struct  Line 920  static void dynticks_rearm_timer(struct 
   
 #endif /* defined(__linux__) */  #endif /* defined(__linux__) */
   
   #if !defined(_WIN32)
   
 static int unix_start_timer(struct qemu_alarm_timer *t)  static int unix_start_timer(struct qemu_alarm_timer *t)
 {  {
     struct sigaction act;      struct sigaction act;
Line 1150  void quit_timers(void) Line 1076  void quit_timers(void)
   
 int qemu_calculate_timeout(void)  int qemu_calculate_timeout(void)
 {  {
 #ifndef CONFIG_IOTHREAD  
     int timeout;      int timeout;
   
   #ifdef CONFIG_IOTHREAD
       /* When using icount, making forward progress with qemu_icount when the
          guest CPU is idle is critical. We only use the static io-thread timeout
          for non icount runs.  */
       if (!use_icount) {
           return 1000;
       }
   #endif
   
     if (!vm_running)      if (!vm_running)
         timeout = 5000;          timeout = 5000;
     else {      else {
Line 1183  int qemu_calculate_timeout(void) Line 1117  int qemu_calculate_timeout(void)
     }      }
   
     return timeout;      return timeout;
 #else /* CONFIG_IOTHREAD */  
     return 1000;  
 #endif  
 }  }
   

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


unix.superglobalmegacorp.com