svn commit: r193814 - in head/sys: amd64/isa i386/isa
Ariff Abdullah
ariff at FreeBSD.org
Tue Jun 9 07:26:53 UTC 2009
Author: ariff
Date: Tue Jun 9 07:26:52 2009
New Revision: 193814
URL: http://svn.freebsd.org/changeset/base/193814
Log:
When using i8254 as the only kernel timer source:
- Interpolate stat/prof clock using clkintr() in a similar fashion to
local APIC timer, since statclock usually run slower.
- Liberate hardclockintr() from taking the burden of handling both stat
and prof clock interrupt. Instead, send IPIs within clkintr() to handle
those.
Modified:
head/sys/amd64/isa/clock.c
head/sys/i386/isa/clock.c
Modified: head/sys/amd64/isa/clock.c
==============================================================================
--- head/sys/amd64/isa/clock.c Tue Jun 9 07:14:32 2009 (r193813)
+++ head/sys/amd64/isa/clock.c Tue Jun 9 07:26:52 2009 (r193814)
@@ -93,6 +93,9 @@ static int i8254_ticked;
static int using_atrtc_timer;
static int using_lapic_timer;
+static u_int stat_ticks = 0;
+static u_int prof_ticks = 0;
+
/* Values for timerX_state: */
#define RELEASED 0
#define RELEASE_PENDING 1
@@ -122,8 +125,6 @@ hardclockintr(struct trapframe *frame)
hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
else
hardclock_cpu(TRAPF_USERMODE(frame));
- if (!using_atrtc_timer)
- statclockintr(frame);
return (FILTER_HANDLED);
}
@@ -131,8 +132,6 @@ int
statclockintr(struct trapframe *frame)
{
- if (profprocs != 0)
- profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
statclock(TRAPF_USERMODE(frame));
return (FILTER_HANDLED);
}
@@ -166,6 +165,30 @@ clkintr(struct trapframe *frame)
ipi_all_but_self(IPI_HARDCLOCK);
#endif
hardclockintr(frame);
+
+ if (!using_atrtc_timer) {
+ prof_ticks += profhz;
+ if (prof_ticks >= hz) {
+ prof_ticks -= hz;
+ if (profprocs != 0) {
+#ifdef SMP
+ if (smp_started)
+ ipi_all_but_self(IPI_PROFCLOCK);
+#endif
+ profclockintr(frame);
+ }
+ }
+ stat_ticks += stathz;
+ if (stat_ticks >= hz) {
+ stat_ticks -= hz;
+#ifdef SMP
+ if (smp_started)
+ ipi_all_but_self(IPI_STATCLOCK);
+#endif
+ statclockintr(frame);
+ }
+ }
+
return (FILTER_HANDLED);
}
@@ -500,7 +523,8 @@ cpu_initclocks()
INTR_TYPE_CLK, NULL);
atrtc_enable_intr();
} else {
- profhz = stathz = hz;
+ profhz = min(RTC_PROFRATE, hz);
+ stathz = min(RTC_NOPROFRATE, hz);
}
}
@@ -511,7 +535,7 @@ void
cpu_startprofclock(void)
{
- if (using_lapic_timer)
+ if (using_lapic_timer || !using_atrtc_clock)
return;
atrtc_rate(RTCSA_PROF);
psdiv = pscnt = psratio;
@@ -521,7 +545,7 @@ void
cpu_stopprofclock(void)
{
- if (using_lapic_timer)
+ if (using_lapic_timer || !using_atrtc_clock)
return;
atrtc_rate(RTCSA_NOPROF);
psdiv = pscnt = 1;
Modified: head/sys/i386/isa/clock.c
==============================================================================
--- head/sys/i386/isa/clock.c Tue Jun 9 07:14:32 2009 (r193813)
+++ head/sys/i386/isa/clock.c Tue Jun 9 07:26:52 2009 (r193814)
@@ -108,6 +108,9 @@ static int i8254_ticked;
static int using_atrtc_timer;
static int using_lapic_timer;
+static u_int stat_ticks = 0;
+static u_int prof_ticks = 0;
+
/* Values for timerX_state: */
#define RELEASED 0
#define RELEASE_PENDING 1
@@ -137,8 +140,6 @@ hardclockintr(struct trapframe *frame)
hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
else
hardclock_cpu(TRAPF_USERMODE(frame));
- if (!using_atrtc_timer)
- statclockintr(frame);
return (FILTER_HANDLED);
}
@@ -146,8 +147,6 @@ int
statclockintr(struct trapframe *frame)
{
- if (profprocs != 0)
- profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
statclock(TRAPF_USERMODE(frame));
return (FILTER_HANDLED);
}
@@ -193,6 +192,30 @@ clkintr(struct trapframe *frame)
ipi_all_but_self(IPI_HARDCLOCK);
#endif
hardclockintr(frame);
+
+ if (!using_atrtc_timer) {
+ prof_ticks += profhz;
+ if (prof_ticks >= hz) {
+ prof_ticks -= hz;
+ if (profprocs != 0) {
+#ifdef SMP
+ if (smp_started)
+ ipi_all_but_self(IPI_PROFCLOCK);
+#endif
+ profclockintr(frame);
+ }
+ }
+ stat_ticks += stathz;
+ if (stat_ticks >= hz) {
+ stat_ticks -= hz;
+#ifdef SMP
+ if (smp_started)
+ ipi_all_but_self(IPI_STATCLOCK);
+#endif
+ statclockintr(frame);
+ }
+ }
+
#ifdef DEV_MCA
/* Reset clock interrupt by asserting bit 7 of port 0x61 */
if (MCA_system)
@@ -549,7 +572,8 @@ cpu_initclocks()
INTR_TYPE_CLK, NULL);
atrtc_enable_intr();
} else {
- profhz = stathz = hz;
+ profhz = min(RTC_PROFRATE, hz);
+ stathz = min(RTC_NOPROFRATE, hz);
}
}
@@ -560,7 +584,7 @@ void
cpu_startprofclock(void)
{
- if (using_lapic_timer)
+ if (using_lapic_timer || !using_atrtc_timer)
return;
atrtc_rate(RTCSA_PROF);
psdiv = pscnt = psratio;
@@ -570,7 +594,7 @@ void
cpu_stopprofclock(void)
{
- if (using_lapic_timer)
+ if (using_lapic_timer || !using_atrtc_timer)
return;
atrtc_rate(RTCSA_NOPROF);
psdiv = pscnt = 1;
More information about the svn-src-all
mailing list