Split statclock into statclock and profclock, and made the method for driving
statclock based on profhz when profiling is enabled MD, since most platforms don't use this anyway. This removes the need for statclock_process, whose only purpose was to subdivide profhz, and gets the profiling clock running outside of sched_lock on platforms that implement suswintr. Also changed the interface for starting and stopping the profiling clock to do just that, instead of changing the rate of statclock, since they can now be separate. Reviewed by: jhb, tmm Tested on: i386, sparc64
This commit is contained in:
parent
ca26842e2a
commit
238dd3209a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=110296
@ -446,17 +446,18 @@ handleclock(void *arg)
|
||||
hardclock(arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* We assume newhz is either stathz or profhz, and that neither will
|
||||
* change after being set up above. Could recalculate intervals here
|
||||
* but that would be a drag.
|
||||
*/
|
||||
void
|
||||
setstatclockrate(newhz)
|
||||
int newhz;
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
|
||||
/* nothing we can do */
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -472,16 +472,19 @@ alpha_clock_interrupt(struct trapframe *framep)
|
||||
#endif
|
||||
(*platform.clockintr)(framep);
|
||||
/* divide hz (1024) by 8 to get stathz (128) */
|
||||
if ((++schedclk2 & 0x7) == 0)
|
||||
if ((++schedclk2 & 0x7) == 0) {
|
||||
if (profprocs != 0)
|
||||
profclock((struct clockframe *)framep);
|
||||
statclock((struct clockframe *)framep);
|
||||
}
|
||||
#ifdef SMP
|
||||
} else {
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, TRAPF_USERMODE(framep));
|
||||
if ((schedclk2 & 0x7) == 0)
|
||||
statclock_process(curkse, TRAPF_PC(framep),
|
||||
TRAPF_USERMODE(framep));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process((struct clockframe *)framep);
|
||||
if ((schedclk2 & 0x7) == 0) {
|
||||
if (profprocs != 0)
|
||||
profclock((struct clockframe *)framep);
|
||||
statclock((struct clockframe *)framep);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
critical_exit();
|
||||
|
@ -365,7 +365,7 @@ Xinvlrng:
|
||||
iret
|
||||
|
||||
/*
|
||||
* Forward hardclock to another CPU. Pushes a trapframe and calls
|
||||
* Forward hardclock to another CPU. Pushes a clockframe and calls
|
||||
* forwarded_hardclock().
|
||||
*/
|
||||
.text
|
||||
@ -389,14 +389,16 @@ Xhardclock:
|
||||
jmp 10f
|
||||
1:
|
||||
incl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
pushl $0 /* XXX convert trapframe to clockframe */
|
||||
call forwarded_hardclock
|
||||
addl $4, %esp /* XXX convert clockframe to trapframe */
|
||||
decl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
10:
|
||||
MEXITCOUNT
|
||||
jmp doreti
|
||||
|
||||
/*
|
||||
* Forward statclock to another CPU. Pushes a trapframe and calls
|
||||
* Forward statclock to another CPU. Pushes a clockframe and calls
|
||||
* forwarded_statclock().
|
||||
*/
|
||||
.text
|
||||
@ -422,7 +424,9 @@ Xstatclock:
|
||||
jmp 10f
|
||||
1:
|
||||
incl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
pushl $0 /* XXX convert trapframe to clockframe */
|
||||
call forwarded_statclock
|
||||
addl $4, %esp /* XXX convert clockframe to trapframe */
|
||||
decl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
10:
|
||||
MEXITCOUNT
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/critical.h>
|
||||
|
||||
#ifdef SMP
|
||||
@ -89,6 +90,10 @@ cpu_thread_link(struct thread *td)
|
||||
void
|
||||
i386_unpend(void)
|
||||
{
|
||||
struct clockframe frame;
|
||||
|
||||
frame.cf_cs = SEL_KPL;
|
||||
frame.cf_eip = (register_t)i386_unpend;
|
||||
KASSERT(curthread->td_critnest == 0, ("unpend critnest != 0"));
|
||||
KASSERT((read_eflags() & PSL_I) == 0, ("unpend interrupts enabled1"));
|
||||
curthread->td_critnest = 1;
|
||||
@ -131,15 +136,13 @@ i386_unpend(void)
|
||||
PCPU_SET(spending, mask & ~(1 << irq));
|
||||
switch(irq) {
|
||||
case 0: /* bit 0 - hardclock */
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, 0);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process(&frame);
|
||||
break;
|
||||
case 1: /* bit 1 - statclock */
|
||||
mtx_lock_spin(&sched_lock);
|
||||
statclock_process(curthread->td_kse,
|
||||
(register_t)i386_unpend, 0);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (profprocs != 0)
|
||||
profclock(&frame);
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
break;
|
||||
}
|
||||
KASSERT((read_eflags() & PSL_I) == 0,
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
#include <machine/apic.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/mpapic.h>
|
||||
@ -2603,17 +2604,17 @@ ap_init(void)
|
||||
* For statclock, we send an IPI to all CPU's to have them call this
|
||||
* function.
|
||||
*
|
||||
* WARNING! unpend() will call statclock_process() directly and skip this
|
||||
* WARNING! unpend() will call statclock() directly and skip this
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_statclock(struct trapframe frame)
|
||||
forwarded_statclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
statclock_process(curthread->td_kse, TRAPF_PC(&frame),
|
||||
TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (profprocs != 0)
|
||||
profclock(&frame);
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2642,12 +2643,10 @@ forward_statclock(void)
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_hardclock(struct trapframe frame)
|
||||
forwarded_hardclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
#include <machine/apic.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/mpapic.h>
|
||||
@ -2603,17 +2604,17 @@ ap_init(void)
|
||||
* For statclock, we send an IPI to all CPU's to have them call this
|
||||
* function.
|
||||
*
|
||||
* WARNING! unpend() will call statclock_process() directly and skip this
|
||||
* WARNING! unpend() will call statclock() directly and skip this
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_statclock(struct trapframe frame)
|
||||
forwarded_statclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
statclock_process(curthread->td_kse, TRAPF_PC(&frame),
|
||||
TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (profprocs != 0)
|
||||
profclock(&frame);
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2642,12 +2643,10 @@ forward_statclock(void)
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_hardclock(struct trapframe frame)
|
||||
forwarded_hardclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -130,6 +130,8 @@ static void setup_8254_mixed_mode(void);
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int clkintr_pending;
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int pscnt = 1;
|
||||
int psdiv = 1;
|
||||
int statclock_disable;
|
||||
#ifndef TIMER_FREQ
|
||||
#define TIMER_FREQ 1193182
|
||||
@ -380,7 +382,13 @@ static void
|
||||
rtcintr(struct clockframe frame)
|
||||
{
|
||||
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
|
||||
statclock(&frame);
|
||||
if (profprocs != 0) {
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
profclock(&frame);
|
||||
}
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
#ifdef SMP
|
||||
forward_statclock();
|
||||
#endif
|
||||
@ -1169,13 +1177,21 @@ setup_8254_mixed_mode()
|
||||
#endif
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
if (newhz == RTC_PROFRATE)
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
else
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = psratio;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
extern int adjkerntz;
|
||||
extern int disable_rtc_set;
|
||||
extern int pscnt;
|
||||
extern int psdiv;
|
||||
extern int statclock_disable;
|
||||
extern u_int timer_freq;
|
||||
extern int timer0_max_count;
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
#include <machine/apic.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/mpapic.h>
|
||||
@ -2603,17 +2604,17 @@ ap_init(void)
|
||||
* For statclock, we send an IPI to all CPU's to have them call this
|
||||
* function.
|
||||
*
|
||||
* WARNING! unpend() will call statclock_process() directly and skip this
|
||||
* WARNING! unpend() will call statclock() directly and skip this
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_statclock(struct trapframe frame)
|
||||
forwarded_statclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
statclock_process(curthread->td_kse, TRAPF_PC(&frame),
|
||||
TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (profprocs != 0)
|
||||
profclock(&frame);
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2642,12 +2643,10 @@ forward_statclock(void)
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_hardclock(struct trapframe frame)
|
||||
forwarded_hardclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -113,9 +113,9 @@ void revoke_apic_irq(int irq);
|
||||
void bsp_apic_configure(void);
|
||||
void init_secondary(void);
|
||||
void forward_statclock(void);
|
||||
void forwarded_statclock(struct trapframe frame);
|
||||
void forwarded_statclock(struct clockframe frame);
|
||||
void forward_hardclock(void);
|
||||
void forwarded_hardclock(struct trapframe frame);
|
||||
void forwarded_hardclock(struct clockframe frame);
|
||||
void ipi_selected(u_int cpus, u_int ipi);
|
||||
void ipi_all(u_int ipi);
|
||||
void ipi_all_but_self(u_int ipi);
|
||||
|
@ -130,6 +130,8 @@ static void setup_8254_mixed_mode(void);
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int clkintr_pending;
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int pscnt = 1;
|
||||
int psdiv = 1;
|
||||
int statclock_disable;
|
||||
#ifndef TIMER_FREQ
|
||||
#define TIMER_FREQ 1193182
|
||||
@ -380,7 +382,13 @@ static void
|
||||
rtcintr(struct clockframe frame)
|
||||
{
|
||||
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
|
||||
statclock(&frame);
|
||||
if (profprocs != 0) {
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
profclock(&frame);
|
||||
}
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
#ifdef SMP
|
||||
forward_statclock();
|
||||
#endif
|
||||
@ -1169,13 +1177,21 @@ setup_8254_mixed_mode()
|
||||
#endif
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
if (newhz == RTC_PROFRATE)
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
else
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = psratio;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -365,7 +365,7 @@ Xinvlrng:
|
||||
iret
|
||||
|
||||
/*
|
||||
* Forward hardclock to another CPU. Pushes a trapframe and calls
|
||||
* Forward hardclock to another CPU. Pushes a clockframe and calls
|
||||
* forwarded_hardclock().
|
||||
*/
|
||||
.text
|
||||
@ -389,14 +389,16 @@ Xhardclock:
|
||||
jmp 10f
|
||||
1:
|
||||
incl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
pushl $0 /* XXX convert trapframe to clockframe */
|
||||
call forwarded_hardclock
|
||||
addl $4, %esp /* XXX convert clockframe to trapframe */
|
||||
decl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
10:
|
||||
MEXITCOUNT
|
||||
jmp doreti
|
||||
|
||||
/*
|
||||
* Forward statclock to another CPU. Pushes a trapframe and calls
|
||||
* Forward statclock to another CPU. Pushes a clockframe and calls
|
||||
* forwarded_statclock().
|
||||
*/
|
||||
.text
|
||||
@ -422,7 +424,9 @@ Xstatclock:
|
||||
jmp 10f
|
||||
1:
|
||||
incl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
pushl $0 /* XXX convert trapframe to clockframe */
|
||||
call forwarded_statclock
|
||||
addl $4, %esp /* XXX convert clockframe to trapframe */
|
||||
decl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
10:
|
||||
MEXITCOUNT
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/critical.h>
|
||||
|
||||
#ifdef SMP
|
||||
@ -89,6 +90,10 @@ cpu_thread_link(struct thread *td)
|
||||
void
|
||||
i386_unpend(void)
|
||||
{
|
||||
struct clockframe frame;
|
||||
|
||||
frame.cf_cs = SEL_KPL;
|
||||
frame.cf_eip = (register_t)i386_unpend;
|
||||
KASSERT(curthread->td_critnest == 0, ("unpend critnest != 0"));
|
||||
KASSERT((read_eflags() & PSL_I) == 0, ("unpend interrupts enabled1"));
|
||||
curthread->td_critnest = 1;
|
||||
@ -131,15 +136,13 @@ i386_unpend(void)
|
||||
PCPU_SET(spending, mask & ~(1 << irq));
|
||||
switch(irq) {
|
||||
case 0: /* bit 0 - hardclock */
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, 0);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process(&frame);
|
||||
break;
|
||||
case 1: /* bit 1 - statclock */
|
||||
mtx_lock_spin(&sched_lock);
|
||||
statclock_process(curthread->td_kse,
|
||||
(register_t)i386_unpend, 0);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (profprocs != 0)
|
||||
profclock(&frame);
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
break;
|
||||
}
|
||||
KASSERT((read_eflags() & PSL_I) == 0,
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
#include <machine/apic.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/mpapic.h>
|
||||
@ -2603,17 +2604,17 @@ ap_init(void)
|
||||
* For statclock, we send an IPI to all CPU's to have them call this
|
||||
* function.
|
||||
*
|
||||
* WARNING! unpend() will call statclock_process() directly and skip this
|
||||
* WARNING! unpend() will call statclock() directly and skip this
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_statclock(struct trapframe frame)
|
||||
forwarded_statclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
statclock_process(curthread->td_kse, TRAPF_PC(&frame),
|
||||
TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (profprocs != 0)
|
||||
profclock(&frame);
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2642,12 +2643,10 @@ forward_statclock(void)
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_hardclock(struct trapframe frame)
|
||||
forwarded_hardclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
#include <machine/apic.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/mpapic.h>
|
||||
@ -2603,17 +2604,17 @@ ap_init(void)
|
||||
* For statclock, we send an IPI to all CPU's to have them call this
|
||||
* function.
|
||||
*
|
||||
* WARNING! unpend() will call statclock_process() directly and skip this
|
||||
* WARNING! unpend() will call statclock() directly and skip this
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_statclock(struct trapframe frame)
|
||||
forwarded_statclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
statclock_process(curthread->td_kse, TRAPF_PC(&frame),
|
||||
TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (profprocs != 0)
|
||||
profclock(&frame);
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2642,12 +2643,10 @@ forward_statclock(void)
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_hardclock(struct trapframe frame)
|
||||
forwarded_hardclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -130,6 +130,8 @@ static void setup_8254_mixed_mode(void);
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int clkintr_pending;
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int pscnt = 1;
|
||||
int psdiv = 1;
|
||||
int statclock_disable;
|
||||
#ifndef TIMER_FREQ
|
||||
#define TIMER_FREQ 1193182
|
||||
@ -380,7 +382,13 @@ static void
|
||||
rtcintr(struct clockframe frame)
|
||||
{
|
||||
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
|
||||
statclock(&frame);
|
||||
if (profprocs != 0) {
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
profclock(&frame);
|
||||
}
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
#ifdef SMP
|
||||
forward_statclock();
|
||||
#endif
|
||||
@ -1169,13 +1177,21 @@ setup_8254_mixed_mode()
|
||||
#endif
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
if (newhz == RTC_PROFRATE)
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
else
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = psratio;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
extern int adjkerntz;
|
||||
extern int disable_rtc_set;
|
||||
extern int pscnt;
|
||||
extern int psdiv;
|
||||
extern int statclock_disable;
|
||||
extern u_int timer_freq;
|
||||
extern int timer0_max_count;
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
#include <machine/apic.h>
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/mpapic.h>
|
||||
@ -2603,17 +2604,17 @@ ap_init(void)
|
||||
* For statclock, we send an IPI to all CPU's to have them call this
|
||||
* function.
|
||||
*
|
||||
* WARNING! unpend() will call statclock_process() directly and skip this
|
||||
* WARNING! unpend() will call statclock() directly and skip this
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_statclock(struct trapframe frame)
|
||||
forwarded_statclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
statclock_process(curthread->td_kse, TRAPF_PC(&frame),
|
||||
TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
if (profprocs != 0)
|
||||
profclock(&frame);
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2642,12 +2643,10 @@ forward_statclock(void)
|
||||
* routine.
|
||||
*/
|
||||
void
|
||||
forwarded_hardclock(struct trapframe frame)
|
||||
forwarded_hardclock(struct clockframe frame)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, TRAPF_USERMODE(&frame));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process(&frame);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -113,9 +113,9 @@ void revoke_apic_irq(int irq);
|
||||
void bsp_apic_configure(void);
|
||||
void init_secondary(void);
|
||||
void forward_statclock(void);
|
||||
void forwarded_statclock(struct trapframe frame);
|
||||
void forwarded_statclock(struct clockframe frame);
|
||||
void forward_hardclock(void);
|
||||
void forwarded_hardclock(struct trapframe frame);
|
||||
void forwarded_hardclock(struct clockframe frame);
|
||||
void ipi_selected(u_int cpus, u_int ipi);
|
||||
void ipi_all(u_int ipi);
|
||||
void ipi_all_but_self(u_int ipi);
|
||||
|
@ -365,7 +365,7 @@ Xinvlrng:
|
||||
iret
|
||||
|
||||
/*
|
||||
* Forward hardclock to another CPU. Pushes a trapframe and calls
|
||||
* Forward hardclock to another CPU. Pushes a clockframe and calls
|
||||
* forwarded_hardclock().
|
||||
*/
|
||||
.text
|
||||
@ -389,14 +389,16 @@ Xhardclock:
|
||||
jmp 10f
|
||||
1:
|
||||
incl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
pushl $0 /* XXX convert trapframe to clockframe */
|
||||
call forwarded_hardclock
|
||||
addl $4, %esp /* XXX convert clockframe to trapframe */
|
||||
decl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
10:
|
||||
MEXITCOUNT
|
||||
jmp doreti
|
||||
|
||||
/*
|
||||
* Forward statclock to another CPU. Pushes a trapframe and calls
|
||||
* Forward statclock to another CPU. Pushes a clockframe and calls
|
||||
* forwarded_statclock().
|
||||
*/
|
||||
.text
|
||||
@ -422,7 +424,9 @@ Xstatclock:
|
||||
jmp 10f
|
||||
1:
|
||||
incl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
pushl $0 /* XXX convert trapframe to clockframe */
|
||||
call forwarded_statclock
|
||||
addl $4, %esp /* XXX convert clockframe to trapframe */
|
||||
decl TD_INTR_NESTING_LEVEL(%ebx)
|
||||
10:
|
||||
MEXITCOUNT
|
||||
|
@ -130,6 +130,8 @@ static void setup_8254_mixed_mode(void);
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int clkintr_pending;
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int pscnt = 1;
|
||||
int psdiv = 1;
|
||||
int statclock_disable;
|
||||
#ifndef TIMER_FREQ
|
||||
#define TIMER_FREQ 1193182
|
||||
@ -380,7 +382,13 @@ static void
|
||||
rtcintr(struct clockframe frame)
|
||||
{
|
||||
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
|
||||
statclock(&frame);
|
||||
if (profprocs != 0) {
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
profclock(&frame);
|
||||
}
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
#ifdef SMP
|
||||
forward_statclock();
|
||||
#endif
|
||||
@ -1169,13 +1177,21 @@ setup_8254_mixed_mode()
|
||||
#endif
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
if (newhz == RTC_PROFRATE)
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
else
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = psratio;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -259,12 +259,19 @@ calibrate_clocks(u_int32_t firmware_freq)
|
||||
* change after being set up above. Could recalculate intervals here
|
||||
* but that would be a drag.
|
||||
*/
|
||||
|
||||
void
|
||||
setstatclockrate(newhz)
|
||||
int newhz;
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
|
||||
/* nothing we can do */
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -132,16 +132,19 @@ interrupt(u_int64_t vector, struct trapframe *framep)
|
||||
#endif
|
||||
hardclock((struct clockframe *)framep);
|
||||
/* divide hz (1024) by 8 to get stathz (128) */
|
||||
if ((++schedclk2 & 0x7) == 0)
|
||||
if ((++schedclk2 & 0x7) == 0) {
|
||||
if (profprocs != 0)
|
||||
profclock((struct clockframe *)framep);
|
||||
statclock((struct clockframe *)framep);
|
||||
}
|
||||
#ifdef SMP
|
||||
} else {
|
||||
mtx_lock_spin(&sched_lock);
|
||||
hardclock_process(curthread, TRAPF_USERMODE(framep));
|
||||
if ((schedclk2 & 0x7) == 0)
|
||||
statclock_process(curkse, TRAPF_PC(framep),
|
||||
TRAPF_USERMODE(framep));
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
hardclock_process((struct clockframe *)framep);
|
||||
if ((schedclk2 & 0x7) == 0) {
|
||||
if (profprocs != 0)
|
||||
profclock((struct clockframe *)framep);
|
||||
statclock((struct clockframe *)framep);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
critical_exit();
|
||||
|
@ -130,6 +130,8 @@ static void setup_8254_mixed_mode(void);
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int clkintr_pending;
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int pscnt = 1;
|
||||
int psdiv = 1;
|
||||
int statclock_disable;
|
||||
#ifndef TIMER_FREQ
|
||||
#define TIMER_FREQ 1193182
|
||||
@ -380,7 +382,13 @@ static void
|
||||
rtcintr(struct clockframe frame)
|
||||
{
|
||||
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
|
||||
statclock(&frame);
|
||||
if (profprocs != 0) {
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
profclock(&frame);
|
||||
}
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
#ifdef SMP
|
||||
forward_statclock();
|
||||
#endif
|
||||
@ -1169,13 +1177,21 @@ setup_8254_mixed_mode()
|
||||
#endif
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
if (newhz == RTC_PROFRATE)
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
else
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_PROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = psratio;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
|
||||
rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
|
||||
writertc(RTC_STATUSA, rtc_statusa);
|
||||
psdiv = pscnt = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -122,10 +122,9 @@ long tk_rawcc;
|
||||
|
||||
int stathz;
|
||||
int profhz;
|
||||
static int profprocs;
|
||||
int profprocs;
|
||||
int ticks;
|
||||
static int psdiv, pscnt; /* prof => stat divider */
|
||||
int psratio; /* ratio: prof / stat */
|
||||
int psratio;
|
||||
|
||||
/*
|
||||
* Initialize clock frequencies and start both clocks running.
|
||||
@ -141,7 +140,6 @@ initclocks(dummy)
|
||||
* Set divisors to 1 (normal case) and let the machine-specific
|
||||
* code do its bit.
|
||||
*/
|
||||
psdiv = pscnt = 1;
|
||||
cpu_initclocks();
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
@ -157,32 +155,27 @@ initclocks(dummy)
|
||||
}
|
||||
|
||||
/*
|
||||
* Each time the real-time timer fires, this function is called on all CPUs
|
||||
* with each CPU passing in its curthread as the first argument. If possible
|
||||
* a nice optimization in the future would be to allow the CPU receiving the
|
||||
* actual real-time timer interrupt to call this function on behalf of the
|
||||
* other CPUs rather than sending an IPI to all other CPUs so that they
|
||||
* can call this function. Note that hardclock() calls hardclock_process()
|
||||
* for the CPU receiving the timer interrupt, so only the other CPUs in the
|
||||
* system need to call this function (or have it called on their behalf.
|
||||
* Each time the real-time timer fires, this function is called on all CPUs.
|
||||
* Note that hardclock() calls hardclock_process() for the boot CPU, so only
|
||||
* the other CPUs in the system need to call this function.
|
||||
*/
|
||||
void
|
||||
hardclock_process(td, user)
|
||||
struct thread *td;
|
||||
int user;
|
||||
hardclock_process(frame)
|
||||
register struct clockframe *frame;
|
||||
{
|
||||
struct pstats *pstats;
|
||||
struct thread *td = curthread;
|
||||
struct proc *p = td->td_proc;
|
||||
|
||||
/*
|
||||
* Run current process's virtual and profile time, as needed.
|
||||
*/
|
||||
mtx_assert(&sched_lock, MA_OWNED);
|
||||
mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
if (p->p_flag & P_KSES) {
|
||||
/* XXXKSE What to do? */
|
||||
} else {
|
||||
pstats = p->p_stats;
|
||||
if (user &&
|
||||
if (CLKF_USERMODE(frame) &&
|
||||
timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) &&
|
||||
itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0) {
|
||||
p->p_sflag |= PS_ALRMPEND;
|
||||
@ -194,6 +187,7 @@ hardclock_process(td, user)
|
||||
td->td_kse->ke_flags |= KEF_ASTPENDING;
|
||||
}
|
||||
}
|
||||
mtx_unlock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -206,9 +200,7 @@ hardclock(frame)
|
||||
int need_softclock = 0;
|
||||
|
||||
CTR0(KTR_CLK, "hardclock fired");
|
||||
mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
hardclock_process(curthread, CLKF_USERMODE(frame));
|
||||
mtx_unlock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
hardclock_process(frame);
|
||||
|
||||
tc_ticktock();
|
||||
/*
|
||||
@ -216,8 +208,10 @@ hardclock(frame)
|
||||
*
|
||||
* XXX: this only works for UP
|
||||
*/
|
||||
if (stathz == 0)
|
||||
if (stathz == 0) {
|
||||
profclock(frame);
|
||||
statclock(frame);
|
||||
}
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
hardclock_device_poll(); /* this is very short and quick */
|
||||
@ -312,7 +306,6 @@ void
|
||||
startprofclock(p)
|
||||
register struct proc *p;
|
||||
{
|
||||
int s;
|
||||
|
||||
/*
|
||||
* XXX; Right now sched_lock protects statclock(), but perhaps
|
||||
@ -322,12 +315,8 @@ startprofclock(p)
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if ((p->p_sflag & PS_PROFIL) == 0) {
|
||||
p->p_sflag |= PS_PROFIL;
|
||||
if (++profprocs == 1 && stathz != 0) {
|
||||
s = splstatclock();
|
||||
psdiv = pscnt = psratio;
|
||||
setstatclockrate(profhz);
|
||||
splx(s);
|
||||
}
|
||||
if (++profprocs == 1)
|
||||
cpu_startprofclock();
|
||||
}
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
@ -339,57 +328,41 @@ void
|
||||
stopprofclock(p)
|
||||
register struct proc *p;
|
||||
{
|
||||
int s;
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
if (p->p_sflag & PS_PROFIL) {
|
||||
p->p_sflag &= ~PS_PROFIL;
|
||||
if (--profprocs == 0 && stathz != 0) {
|
||||
s = splstatclock();
|
||||
psdiv = pscnt = 1;
|
||||
setstatclockrate(stathz);
|
||||
splx(s);
|
||||
}
|
||||
if (--profprocs == 0)
|
||||
cpu_stopprofclock();
|
||||
}
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do process and kernel statistics. Most of the statistics are only
|
||||
* Statistics clock. Grab profile sample, and if divider reaches 0,
|
||||
* do process and kernel statistics. Most of the statistics are only
|
||||
* used by user-level statistics programs. The main exceptions are
|
||||
* ke->ke_uticks, p->p_sticks, p->p_iticks, and p->p_estcpu. This function
|
||||
* should be called by all CPUs in the system for each statistics clock
|
||||
* interrupt. See the description of hardclock_process for more detail on
|
||||
* this function's relationship to statclock.
|
||||
* ke->ke_uticks, p->p_sticks, p->p_iticks, and p->p_estcpu.
|
||||
* This should be called by all active processors.
|
||||
*/
|
||||
void
|
||||
statclock_process(ke, pc, user)
|
||||
struct kse *ke;
|
||||
register_t pc;
|
||||
int user;
|
||||
statclock(frame)
|
||||
register struct clockframe *frame;
|
||||
{
|
||||
#ifdef GPROF
|
||||
struct gmonparam *g;
|
||||
int i;
|
||||
#endif
|
||||
struct pstats *pstats;
|
||||
long rss;
|
||||
struct rusage *ru;
|
||||
struct vmspace *vm;
|
||||
struct proc *p = ke->ke_proc;
|
||||
struct thread *td = ke->ke_thread; /* current thread */
|
||||
struct thread *td;
|
||||
struct kse *ke;
|
||||
struct proc *p;
|
||||
long rss;
|
||||
|
||||
KASSERT(ke == curthread->td_kse, ("statclock_process: td != curthread"));
|
||||
mtx_assert(&sched_lock, MA_OWNED);
|
||||
if (user) {
|
||||
/*
|
||||
* Came from user mode; CPU was in user state.
|
||||
* If this process is being profiled, record the tick.
|
||||
*/
|
||||
if (p->p_sflag & PS_PROFIL)
|
||||
addupc_intr(ke, pc, 1);
|
||||
if (pscnt < psdiv)
|
||||
return;
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
|
||||
mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
ke = td->td_kse;
|
||||
if (CLKF_USERMODE(frame)) {
|
||||
/*
|
||||
* Charge the time as appropriate.
|
||||
*/
|
||||
@ -401,21 +374,6 @@ statclock_process(ke, pc, user)
|
||||
else
|
||||
cp_time[CP_USER]++;
|
||||
} else {
|
||||
#ifdef GPROF
|
||||
/*
|
||||
* Kernel statistics are just like addupc_intr, only easier.
|
||||
*/
|
||||
g = &_gmonparam;
|
||||
if (g->state == GMON_PROF_ON) {
|
||||
i = pc - g->lowpc;
|
||||
if (i < g->textsize) {
|
||||
i /= HISTFRACTION * sizeof(*g->kcount);
|
||||
g->kcount[i]++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (pscnt < psdiv)
|
||||
return;
|
||||
/*
|
||||
* Came from kernel mode, so we were:
|
||||
* - handling an interrupt,
|
||||
@ -455,25 +413,43 @@ statclock_process(ke, pc, user)
|
||||
if (ru->ru_maxrss < rss)
|
||||
ru->ru_maxrss = rss;
|
||||
}
|
||||
mtx_unlock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Statistics clock. Grab profile sample, and if divider reaches 0,
|
||||
* do process and kernel statistics. Most of the statistics are only
|
||||
* used by user-level statistics programs. The main exceptions are
|
||||
* ke->ke_uticks, p->p_sticks, p->p_iticks, and p->p_estcpu.
|
||||
*/
|
||||
void
|
||||
statclock(frame)
|
||||
profclock(frame)
|
||||
register struct clockframe *frame;
|
||||
{
|
||||
struct thread *td;
|
||||
#ifdef GPROF
|
||||
struct gmonparam *g;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
CTR0(KTR_CLK, "statclock fired");
|
||||
mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
statclock_process(curthread->td_kse, CLKF_PC(frame), CLKF_USERMODE(frame));
|
||||
mtx_unlock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
if (CLKF_USERMODE(frame)) {
|
||||
/*
|
||||
* Came from user mode; CPU was in user state.
|
||||
* If this process is being profiled, record the tick.
|
||||
*/
|
||||
td = curthread;
|
||||
if (td->td_proc->p_sflag & PS_PROFIL)
|
||||
addupc_intr(td->td_kse, CLKF_PC(frame), 1);
|
||||
}
|
||||
#ifdef GPROF
|
||||
else {
|
||||
/*
|
||||
* Kernel statistics are just like addupc_intr, only easier.
|
||||
*/
|
||||
g = &_gmonparam;
|
||||
if (g->state == GMON_PROF_ON) {
|
||||
i = CLKF_PC(frame) - g->lowpc;
|
||||
if (i < g->textsize) {
|
||||
i /= HISTFRACTION * sizeof(*g->kcount);
|
||||
g->kcount[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -140,6 +140,8 @@ static void setup_8254_mixed_mode(void);
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int clkintr_pending;
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int pscnt = 1;
|
||||
int psdiv = 1;
|
||||
int statclock_disable;
|
||||
#ifndef TIMER_FREQ
|
||||
#ifdef PC98
|
||||
@ -441,7 +443,13 @@ static void
|
||||
rtcintr(struct clockframe frame)
|
||||
{
|
||||
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
|
||||
statclock(&frame);
|
||||
if (profprocs != 0) {
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
profclock(&frame);
|
||||
}
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
#ifdef SMP
|
||||
forward_statclock();
|
||||
#endif
|
||||
@ -1518,7 +1526,7 @@ setup_8254_mixed_mode()
|
||||
#endif
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
#ifndef PC98
|
||||
if (newhz == RTC_PROFRATE)
|
||||
@ -1529,6 +1537,11 @@ setstatclockrate(int newhz)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
|
@ -140,6 +140,8 @@ static void setup_8254_mixed_mode(void);
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int clkintr_pending;
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int pscnt = 1;
|
||||
int psdiv = 1;
|
||||
int statclock_disable;
|
||||
#ifndef TIMER_FREQ
|
||||
#ifdef PC98
|
||||
@ -441,7 +443,13 @@ static void
|
||||
rtcintr(struct clockframe frame)
|
||||
{
|
||||
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
|
||||
statclock(&frame);
|
||||
if (profprocs != 0) {
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
profclock(&frame);
|
||||
}
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
#ifdef SMP
|
||||
forward_statclock();
|
||||
#endif
|
||||
@ -1518,7 +1526,7 @@ setup_8254_mixed_mode()
|
||||
#endif
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
#ifndef PC98
|
||||
if (newhz == RTC_PROFRATE)
|
||||
@ -1529,6 +1537,11 @@ setstatclockrate(int newhz)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
|
@ -140,6 +140,8 @@ static void setup_8254_mixed_mode(void);
|
||||
int adjkerntz; /* local offset from GMT in seconds */
|
||||
int clkintr_pending;
|
||||
int disable_rtc_set; /* disable resettodr() if != 0 */
|
||||
int pscnt = 1;
|
||||
int psdiv = 1;
|
||||
int statclock_disable;
|
||||
#ifndef TIMER_FREQ
|
||||
#ifdef PC98
|
||||
@ -441,7 +443,13 @@ static void
|
||||
rtcintr(struct clockframe frame)
|
||||
{
|
||||
while (rtcin(RTC_INTR) & RTCIR_PERIOD) {
|
||||
statclock(&frame);
|
||||
if (profprocs != 0) {
|
||||
if (--pscnt == 0)
|
||||
pscnt = psdiv;
|
||||
profclock(&frame);
|
||||
}
|
||||
if (pscnt == psdiv)
|
||||
statclock(&frame);
|
||||
#ifdef SMP
|
||||
forward_statclock();
|
||||
#endif
|
||||
@ -1518,7 +1526,7 @@ setup_8254_mixed_mode()
|
||||
#endif
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
#ifndef PC98
|
||||
if (newhz == RTC_PROFRATE)
|
||||
@ -1529,6 +1537,11 @@ setstatclockrate(int newhz)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_machdep_i8254_freq(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
|
@ -319,8 +319,13 @@ delay(int n)
|
||||
* Nothing to do.
|
||||
*/
|
||||
void
|
||||
setstatclockrate(int arg)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
}
|
||||
|
@ -319,8 +319,13 @@ delay(int n)
|
||||
* Nothing to do.
|
||||
*/
|
||||
void
|
||||
setstatclockrate(int arg)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
}
|
||||
|
@ -48,9 +48,13 @@ DELAY(int n)
|
||||
}
|
||||
|
||||
void
|
||||
setstatclockrate(int newhz)
|
||||
cpu_startprofclock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
cpu_stopprofclock(void)
|
||||
{
|
||||
/* TODO; */
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -57,6 +57,7 @@ int tick_missed; /* statistics */
|
||||
void
|
||||
cpu_initclocks(void)
|
||||
{
|
||||
stathz = hz;
|
||||
tick_start(tick_hardclock);
|
||||
}
|
||||
|
||||
@ -64,20 +65,13 @@ static __inline void
|
||||
tick_process(struct clockframe *cf)
|
||||
{
|
||||
|
||||
#ifdef SMP
|
||||
if (PCPU_GET(cpuid) == 0)
|
||||
hardclock(cf);
|
||||
else {
|
||||
CTR1(KTR_CLK, "tick_process: AP, cpuid=%d", PCPU_GET(cpuid));
|
||||
mtx_lock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
hardclock_process(curthread, CLKF_USERMODE(cf));
|
||||
statclock_process(curthread->td_kse, CLKF_PC(cf),
|
||||
CLKF_USERMODE(cf));
|
||||
mtx_unlock_spin_flags(&sched_lock, MTX_QUIET);
|
||||
}
|
||||
#else
|
||||
hardclock(cf);
|
||||
#endif
|
||||
else
|
||||
hardclock_process(cf);
|
||||
if (profprocs != 0)
|
||||
profclock(cf);
|
||||
statclock(cf);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -75,6 +75,7 @@ extern int hz; /* system clock's frequency */
|
||||
extern int psratio; /* ratio: prof / stat */
|
||||
extern int stathz; /* statistics clock's frequency */
|
||||
extern int profhz; /* profiling clock's frequency */
|
||||
extern int profprocs; /* number of process's profiling */
|
||||
extern int ticks;
|
||||
extern int lbolt; /* once a second sleep address */
|
||||
|
||||
|
@ -199,14 +199,15 @@ int suword64(void *base, int64_t word);
|
||||
void realitexpire(void *);
|
||||
|
||||
void hardclock(struct clockframe *frame);
|
||||
void hardclock_process(struct thread *td, int user);
|
||||
void hardclock_process(struct clockframe *frame);
|
||||
void softclock(void *);
|
||||
void statclock(struct clockframe *frame);
|
||||
void statclock_process(struct kse *ke, register_t pc, int user);
|
||||
void profclock(struct clockframe *frame);
|
||||
|
||||
void startprofclock(struct proc *);
|
||||
void stopprofclock(struct proc *);
|
||||
void setstatclockrate(int hzrate);
|
||||
void cpu_startprofclock(void);
|
||||
void cpu_stopprofclock(void);
|
||||
|
||||
/* flags for suser() and suser_cred() */
|
||||
#define PRISON_ROOT 1
|
||||
|
Loading…
Reference in New Issue
Block a user