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