summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_clock.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2010-05-24 11:40:49 +0000
committermav <mav@FreeBSD.org>2010-05-24 11:40:49 +0000
commit48198e3ddd922d3260be990c8ecc8fc16f27d470 (patch)
treeba159db619ea3e7bf5e0ee0418e43865078c742f /sys/kern/kern_clock.c
parent598285f6f9f5354c0c6d341c1c8cd78e9981c0f5 (diff)
downloadFreeBSD-src-48198e3ddd922d3260be990c8ecc8fc16f27d470.zip
FreeBSD-src-48198e3ddd922d3260be990c8ecc8fc16f27d470.tar.gz
- Implement MI helper functions, dividing one or two timer interrupts with
arbitrary frequencies into hardclock(), statclock() and profclock() calls. Same code with minor variations duplicated several times over the tree for different timer drivers and architectures. - Switch all x86 archs to new functions, simplifying the code and removing extra logic from timer drivers. Other archs are also welcome.
Diffstat (limited to 'sys/kern/kern_clock.c')
-rw-r--r--sys/kern/kern_clock.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index da05cc1..a35e43b 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -374,6 +374,12 @@ int profprocs;
int ticks;
int psratio;
+int timer1hz;
+int timer2hz;
+static DPCPU_DEFINE(u_int, hard_cnt);
+static DPCPU_DEFINE(u_int, stat_cnt);
+static DPCPU_DEFINE(u_int, prof_cnt);
+
/*
* Initialize clock frequencies and start both clocks running.
*/
@@ -403,6 +409,52 @@ initclocks(dummy)
#endif
}
+void
+timer1clock(int usermode, uintfptr_t pc)
+{
+ u_int *cnt;
+
+ cnt = DPCPU_PTR(hard_cnt);
+ *cnt += hz;
+ if (*cnt >= timer1hz) {
+ *cnt -= timer1hz;
+ if (*cnt >= timer1hz)
+ *cnt = 0;
+ if (PCPU_GET(cpuid) == 0)
+ hardclock(usermode, pc);
+ else
+ hardclock_cpu(usermode);
+ }
+ if (timer2hz == 0)
+ timer2clock(usermode, pc);
+}
+
+void
+timer2clock(int usermode, uintfptr_t pc)
+{
+ u_int *cnt;
+ int t2hz = timer2hz ? timer2hz : timer1hz;
+
+ cnt = DPCPU_PTR(stat_cnt);
+ *cnt += stathz;
+ if (*cnt >= t2hz) {
+ *cnt -= t2hz;
+ if (*cnt >= t2hz)
+ *cnt = 0;
+ statclock(usermode);
+ }
+ if (profprocs == 0)
+ return;
+ cnt = DPCPU_PTR(prof_cnt);
+ *cnt += profhz;
+ if (*cnt >= t2hz) {
+ *cnt -= t2hz;
+ if (*cnt >= t2hz)
+ *cnt = 0;
+ profclock(usermode, pc);
+ }
+}
+
/*
* Each time the real-time timer fires, this function is called on all CPUs.
* Note that hardclock() calls hardclock_cpu() for the boot CPU, so only
OpenPOWER on IntegriCloud