NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/26470: all process stop for a long time by calling settimeofday() and setitimer()



The following reply was made to PR kern/26470; it has been noted by GNATS.

From: Joerg Sonnenberger <joerg%britannica.bec.de@localhost>
To: gnats-bugs%gnats.netbsd.org@localhost
Cc: 
Subject: Re: kern/26470: all process stop for a long time by calling
        settimeofday() and setitimer()
Date: Fri, 23 May 2008 15:03:10 +0200

 --HlL+5n6rz5pIUxbD
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 Hi Saitoh-san,
 I would use the following patch, it is IMO cleaner and easier.
 What do you think?
 
 Joerg
 
 --HlL+5n6rz5pIUxbD
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="kern_time.c.diff"
 
 Index: kern_time.c
 ===================================================================
 RCS file: /data/repo/netbsd/src/sys/kern/kern_time.c,v
 retrieving revision 1.147
 diff -u -p -r1.147 kern_time.c
 --- kern_time.c        8 May 2008 18:56:58 -0000       1.147
 +++ kern_time.c        23 May 2008 13:00:10 -0000
 @@ -923,6 +923,7 @@ sys_timer_getoverrun(struct lwp *l, cons
  void
  realtimerexpire(void *arg)
  {
 +      uint64_t last_val, next_val, interval, now_ms;
        struct timeval now;
        struct ptimer *pt;
  
 @@ -936,24 +937,30 @@ realtimerexpire(void *arg)
                mutex_spin_exit(&timer_lock);
                return;
        }
 -      for (;;) {
 -              timeradd(&pt->pt_time.it_value,
 -                  &pt->pt_time.it_interval, &pt->pt_time.it_value);
 -              getmicrotime(&now);
 -              if (timercmp(&pt->pt_time.it_value, &now, >)) {
 -                      /*
 -                       * Don't need to check hzto() return value, here.
 -                       * callout_reset() does it for us.
 -                       */
 -                      callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value),
 -                          realtimerexpire, pt);
 -                      mutex_spin_exit(&timer_lock);
 -                      return;
 -              }
 -              mutex_spin_exit(&timer_lock);
 -              pt->pt_overruns++;
 -              mutex_spin_enter(&timer_lock);
 +
 +      getmicrotime(&now);
 +      if (timercmp(&pt->pt_time.it_value, &now, <=)) {
 +#define TV2MS(x) (((uint64_t)(x)->tv_sec) * 1000000 + (x)->tv_usec)
 +              now_ms = TV2MS(&now);
 +              last_val = TV2MS(&pt->pt_time.it_value);
 +              interval = TV2MS(&pt->pt_time.it_interval);
 +#undef TV2MS
 +
 +              next_val = now_ms +
 +                  (now_ms - last_val + interval - 1) % interval;
 +              pt->pt_overruns = (now_ms - last_val) / interval;
 +
 +              pt->pt_time.it_value.tv_sec = next_val / 1000000;
 +              pt->pt_time.it_value.tv_usec = next_val % 1000000;
        }
 +
 +      /*
 +       * Don't need to check hzto() return value, here.
 +       * callout_reset() does it for us.
 +       */
 +      callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value),
 +          realtimerexpire, pt);
 +      mutex_spin_exit(&timer_lock);
  }
  
  /* BSD routine to get the value of an interval timer. */
 
 --HlL+5n6rz5pIUxbD--
 


Home | Main Index | Thread Index | Old Index