DragonFly bugs List (threaded) for 2004-07
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
(patch) Re: pmtimer and nanouptime
Please try this patch.
-Matt
Index: i386/isa/clock.c
===================================================================
RCS file: /cvs/src/sys/i386/isa/clock.c,v
retrieving revision 1.15
diff -u -r1.15 clock.c
--- i386/isa/clock.c 20 Jul 2004 04:12:08 -0000 1.15
+++ i386/isa/clock.c 20 Jul 2004 19:02:13 -0000
@@ -596,17 +596,21 @@
}
/*
- * Restore all the timers non-atomically (XXX: should be atomically).
+ * Restore all the timers.
*
- * This function is called from apm_default_resume() to restore all the timers.
- * This should not be necessary, but there are broken laptops that do not
- * restore all the timers on resume.
+ * This function is called from apm_default_resume() / pmtimer to restore
+ * all the timers. We also have to restore our timebases, especially on
+ * MP systems, because cputimer_count() counter's delta may have grown
+ * too large for nanouptime() and friends to handle.
*/
void
timer_restore(void)
{
+ crit_enter();
i8254_restore(); /* restore timer_freq and hz */
rtc_restore(); /* reenable RTC interrupts */
+ restoreclocks();
+ crit_exit();
}
/*
Index: kern/kern_clock.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_clock.c,v
retrieving revision 1.21
diff -u -r1.21 kern_clock.c
--- kern/kern_clock.c 16 Jul 2004 05:51:09 -0000 1.21
+++ kern/kern_clock.c 20 Jul 2004 19:05:49 -0000
@@ -196,6 +196,36 @@
}
/*
+ * Resynchronize gd_cpuclock_base after the system has been woken up from
+ * a sleep. It is absolutely essential that all the cpus be properly
+ * synchronized. Resynching is required because nanouptime() and friends
+ * will overflow intermediate multiplications if more then 2 seconds
+ * worth of cputimer_cont() delta has built up.
+ */
+#ifdef SMP
+
+static
+void
+restoreclocks_remote(lwkt_cpusync_t poll)
+{
+ mycpu->gd_cpuclock_base = *(sysclock_t *)poll->cs_data;
+ mycpu->gd_time_seconds = globaldata_find(0)->gd_time_seconds;
+}
+
+#endif
+
+void
+restoreclocks(void)
+{
+ sysclock_t base = cputimer_count();
+#ifdef SMP
+ lwkt_cpusync_simple(-1, restoreclocks_remote, &base);
+#else
+ mycpu->gd_cpuclock_base = base;
+#endif
+}
+
+/*
* This sets the current real time of day. Timespecs are in seconds and
* nanoseconds. We do not mess with gd_time_seconds and gd_cpuclock_base,
* instead we adjust basetime so basetime + gd_* results in the current
Index: sys/time.h
===================================================================
RCS file: /cvs/src/sys/sys/time.h,v
retrieving revision 1.8
diff -u -r1.8 time.h
--- sys/time.h 30 Jan 2004 05:42:18 -0000 1.8
+++ sys/time.h 20 Jul 2004 19:02:43 -0000
@@ -192,6 +192,7 @@
extern time_t time_second;
void initclocks_pcpu(void);
+void restoreclocks(void);
void getmicrouptime (struct timeval *tv);
void getmicrotime (struct timeval *tv);
void getnanouptime (struct timespec *tv);
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]