This is a patch to MFC what I think are all the calcru-related changes
that occurred since 6-STABLE was branched and 7.0 continued forward.
If anyone spots some changes I missed, please yell out.
--
-- David (obrien@FreeBSD.org)
Index: amd64/amd64/mp_machdep.c
==================================================================RCS file:
/home/ncvs/src/sys/amd64/amd64/mp_machdep.c,v
retrieving revision 1.260.2.11
diff -u -p -r1.260.2.11 mp_machdep.c
--- amd64/amd64/mp_machdep.c 5 May 2007 21:13:16 -0000 1.260.2.11
+++ amd64/amd64/mp_machdep.c 23 Aug 2007 18:05:54 -0000
@@ -577,7 +577,7 @@ init_secondary(void)
spinlock_exit();
KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid
count"));
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
cpu_throw(NULL, choosethread()); /* doesn't return */
Index: amd64/amd64/trap.c
==================================================================RCS file:
/home/ncvs/src/sys/amd64/amd64/trap.c,v
retrieving revision 1.289.2.6
diff -u -p -r1.289.2.6 trap.c
--- amd64/amd64/trap.c 14 Aug 2007 19:42:51 -0000 1.289.2.6
+++ amd64/amd64/trap.c 23 Aug 2007 20:28:33 -0000
@@ -162,7 +162,7 @@ trap(frame)
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
- u_int sticks = 0, type;
+ u_int type;
int i = 0, ucode = 0, code;
PCPU_LAZY_INC(cnt.v_trap);
@@ -242,7 +242,7 @@ trap(frame)
if (ISPL(frame.tf_cs) == SEL_UPL) {
/* user trap */
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = &frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -488,7 +488,7 @@ trap(frame)
#endif
user:
- userret(td, &frame, sticks);
+ userret(td, &frame);
mtx_assert(&Giant, MA_NOTOWNED);
userout:
out:
@@ -703,7 +703,6 @@ syscall(frame)
struct thread *td = curthread;
struct proc *p = td->td_proc;
register_t orig_tf_rflags;
- u_int sticks;
int error;
int narg;
register_t args[8];
@@ -728,7 +727,7 @@ syscall(frame)
reg = 0;
regcnt = 6;
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = &frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -851,7 +850,7 @@ syscall(frame)
/*
* Handle reschedule and other end-of-syscall issues
*/
- userret(td, &frame, sticks);
+ userret(td, &frame);
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code);
Index: amd64/amd64/tsc.c
==================================================================RCS file:
/home/ncvs/src/sys/amd64/amd64/tsc.c,v
retrieving revision 1.205
diff -u -p -r1.205 tsc.c
--- amd64/amd64/tsc.c 17 Nov 2003 08:58:13 -0000 1.205
+++ amd64/amd64/tsc.c 23 Aug 2007 20:32:25 -0000
@@ -77,6 +77,7 @@ init_TSC(void)
tsc_freq = tscval[1] - tscval[0];
if (bootverbose)
printf("TSC clock: %lu Hz\n", tsc_freq);
+ set_cputicker(rdtsc, tsc_freq, 1);
}
Index: amd64/ia32/ia32_syscall.c
==================================================================RCS file:
/home/ncvs/src/sys/amd64/ia32/ia32_syscall.c,v
retrieving revision 1.8.2.2
diff -u -p -r1.8.2.2 ia32_syscall.c
--- amd64/ia32/ia32_syscall.c 11 Aug 2006 18:42:48 -0000 1.8.2.2
+++ amd64/ia32/ia32_syscall.c 23 Aug 2007 18:11:09 -0000
@@ -96,7 +96,6 @@ ia32_syscall(struct trapframe frame)
struct thread *td = curthread;
struct proc *p = td->td_proc;
register_t orig_tf_rflags;
- u_int sticks;
int error;
int narg;
u_int32_t args[8];
@@ -109,7 +108,7 @@ ia32_syscall(struct trapframe frame)
*/
PCPU_LAZY_INC(cnt.v_syscall);
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = &frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -239,7 +238,7 @@ ia32_syscall(struct trapframe frame)
/*
* Handle reschedule and other end-of-syscall issues
*/
- userret(td, &frame, sticks);
+ userret(td, &frame);
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code);
Index: arm/arm/trap.c
==================================================================RCS file:
/home/ncvs/src/sys/arm/arm/trap.c,v
retrieving revision 1.17.2.3
diff -u -p -r1.17.2.3 trap.c
--- arm/arm/trap.c 26 Feb 2007 20:38:31 -0000 1.17.2.3
+++ arm/arm/trap.c 23 Aug 2007 20:27:08 -0000
@@ -230,7 +230,6 @@ data_abort_handler(trapframe_t *tf)
vm_prot_t ftype;
void *onfault;
vm_offset_t va;
- u_int sticks = 0;
int error = 0;
struct ksig ksig;
struct proc *p;
@@ -257,7 +256,8 @@ data_abort_handler(trapframe_t *tf)
user = TRAP_USERMODE(tf);
if (user) {
- sticks = td->td_sticks;
td->td_frame = tf;
+ td->td_pticks = 0;
+ td->td_frame = tf;
if (td->td_ucred != td->td_proc->p_ucred)
cred_update_thread(td);
if (td->td_pflags & TDP_SA)
@@ -463,7 +463,7 @@ do_trapsignal:
out:
/* If returning to user mode, make sure to invoke userret() */
if (user)
- userret(td, tf, sticks);
+ userret(td, tf);
}
/*
@@ -705,7 +705,6 @@ prefetch_abort_handler(trapframe_t *tf)
struct vm_map *map;
vm_offset_t fault_pc, va;
int error = 0;
- u_int sticks = 0;
struct ksig ksig;
@@ -755,7 +754,7 @@ prefetch_abort_handler(trapframe_t *tf)
/* Prefetch aborts cannot happen in kernel mode */
if (__predict_false(!TRAP_USERMODE(tf)))
dab_fatal(tf, 0, tf->tf_pc, NULL, &ksig);
- sticks = td->td_sticks;
+ td->td_pticks = 0;
/* Ok validate the address, can only execute in USER space */
@@ -810,7 +809,7 @@ do_trapsignal:
call_trapsignal(td, ksig.signb, ksig.code);
out:
- userret(td, tf, sticks);
+ userret(td, tf);
}
@@ -872,10 +871,9 @@ syscall(struct thread *td, trapframe_t *
register_t *ap, *args, copyargs[MAXARGS];
struct sysent *callp;
int locked = 0;
- u_int sticks = 0;
PCPU_LAZY_INC(cnt.v_syscall);
- sticks = td->td_sticks;
+ td->td_pticks = 0;
if (td->td_ucred != td->td_proc->p_ucred)
cred_update_thread(td);
switch (insn & SWI_OS_MASK) {
@@ -884,11 +882,11 @@ syscall(struct thread *td, trapframe_t *
break;
default:
trapsignal(td, SIGILL, 0);
- userret(td, frame, td->td_sticks);
+ userret(td, frame);
return;
}
code = insn & 0x000fffff;
- sticks = td->td_sticks;
+ td->td_pticks = 0;
ap = &frame->tf_r0;
if (code == SYS_syscall) {
code = *ap++;
@@ -974,7 +972,7 @@ bad:
mtx_unlock(&Giant);
- userret(td, frame, sticks);
+ userret(td, frame);
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code);
@@ -996,6 +994,7 @@ swi_handler(trapframe_t *frame)
td->td_frame = frame;
+ td->td_pticks = 0;
if (td->td_proc->p_flag & P_SA)
thread_user_enter(td);
/*
@@ -1004,7 +1003,7 @@ swi_handler(trapframe_t *frame)
*/
if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
trapsignal(td, SIGILL, 0);
- userret(td, frame, td->td_sticks);
+ userret(td, frame);
return;
}
insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE);
Index: i386/i386/geode.c
==================================================================RCS file:
/home/ncvs/src/sys/i386/i386/geode.c,v
retrieving revision 1.5.8.2
diff -u -p -r1.5.8.2 geode.c
--- i386/i386/geode.c 30 Mar 2007 19:17:37 -0000 1.5.8.2
+++ i386/i386/geode.c 23 Aug 2007 20:32:25 -0000
@@ -110,6 +110,20 @@ static struct timecounter geode_timecoun
1000
};
+static uint64_t
+geode_cputicks(void)
+{
+ unsigned c;
+ static unsigned last;
+ static uint64_t offset;
+
+ c = inl(geode_counter);
+ if (c < last)
+ offset += (1LL << 32);
+ last = c;
+ return (offset | c);
+}
+
/*
* The GEODE watchdog runs from a 32kHz frequency. One period of that is
* 31250 nanoseconds which we round down to 2^14 nanoseconds. The watchdog
@@ -176,6 +190,7 @@ geode_probe(device_t self)
tc_init(&geode_timecounter);
EVENTHANDLER_REGISTER(watchdog_list, geode_watchdog,
NULL, 0);
+ set_cputicker(geode_cputicks, 27000000, 0);
}
} else if (pci_get_devid(self) == 0x0510100b) {
gpio = pci_read_config(self, PCIR_BAR(0), 4);
Index: i386/i386/mp_machdep.c
==================================================================RCS file:
/home/ncvs/src/sys/i386/i386/mp_machdep.c,v
retrieving revision 1.252.2.11
diff -u -p -r1.252.2.11 mp_machdep.c
--- i386/i386/mp_machdep.c 2 May 2007 16:16:57 -0000 1.252.2.11
+++ i386/i386/mp_machdep.c 23 Aug 2007 18:05:54 -0000
@@ -650,7 +650,7 @@ init_secondary(void)
spinlock_exit();
KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid
count"));
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
cpu_throw(NULL, choosethread()); /* doesn't return */
Index: i386/i386/trap.c
==================================================================RCS file:
/home/ncvs/src/sys/i386/i386/trap.c,v
retrieving revision 1.277.2.6
diff -u -p -r1.277.2.6 trap.c
--- i386/i386/trap.c 14 Aug 2007 19:42:52 -0000 1.277.2.6
+++ i386/i386/trap.c 23 Aug 2007 20:27:51 -0000
@@ -176,7 +176,7 @@ trap(frame)
{
struct thread *td = curthread;
struct proc *p = td->td_proc;
- u_int sticks = 0, type;
+ u_int type;
int i = 0, ucode = 0, code;
vm_offset_t eva;
#ifdef POWERFAIL_NMI
@@ -275,7 +275,7 @@ trap(frame)
!(PCPU_GET(curpcb)->pcb_flags & PCB_VM86CALL))) {
/* user trap */
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = &frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -650,7 +650,7 @@ trap(frame)
#endif
user:
- userret(td, &frame, sticks);
+ userret(td, &frame);
mtx_assert(&Giant, MA_NOTOWNED);
userout:
out:
@@ -881,7 +881,6 @@ syscall(frame)
struct thread *td = curthread;
struct proc *p = td->td_proc;
register_t orig_tf_eflags;
- u_int sticks;
int error;
int narg;
int args[8];
@@ -902,7 +901,7 @@ syscall(frame)
}
#endif
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = &frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -1032,7 +1031,7 @@ syscall(frame)
/*
* Handle reschedule and other end-of-syscall issues
*/
- userret(td, &frame, sticks);
+ userret(td, &frame);
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code);
Index: i386/i386/tsc.c
==================================================================RCS file:
/home/ncvs/src/sys/i386/i386/tsc.c,v
retrieving revision 1.204
diff -u -p -r1.204 tsc.c
--- i386/i386/tsc.c 21 Oct 2003 18:28:34 -0000 1.204
+++ i386/i386/tsc.c 23 Aug 2007 20:32:25 -0000
@@ -86,6 +86,7 @@ init_TSC(void)
tsc_freq = tscval[1] - tscval[0];
if (bootverbose)
printf("TSC clock: %ju Hz\n", (intmax_t)tsc_freq);
+ set_cputicker(rdtsc, tsc_freq, 1);
}
Index: ia64/ia32/ia32_trap.c
==================================================================RCS file:
/home/ncvs/src/sys/ia64/ia32/ia32_trap.c,v
retrieving revision 1.5.2.3
diff -u -p -r1.5.2.3 ia32_trap.c
--- ia64/ia32/ia32_trap.c 19 Sep 2006 12:38:08 -0000 1.5.2.3
+++ ia64/ia32/ia32_trap.c 23 Aug 2007 20:29:46 -0000
@@ -217,7 +217,6 @@ ia32_trap(int vector, struct trapframe *
struct thread *td;
uint64_t ucode;
int sig;
- u_int sticks;
KASSERT(TRAPF_USERMODE(tf), ("%s: In kernel mode???", __func__));
@@ -226,7 +225,7 @@ ia32_trap(int vector, struct trapframe *
td = curthread;
td->td_frame = tf;
- sticks = td->td_sticks;
+ td->td_pticks = 0;
p = td->td_proc;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -304,7 +303,7 @@ ia32_trap(int vector, struct trapframe *
trapsignal(td, sig, ucode);
out:
- userret(td, tf, sticks);
+ userret(td, tf);
mtx_assert(&Giant, MA_NOTOWNED);
do_ast(tf);
}
Index: ia64/ia64/mp_machdep.c
==================================================================RCS file:
/home/ncvs/src/sys/ia64/ia64/mp_machdep.c,v
retrieving revision 1.55.2.2
diff -u -p -r1.55.2.2 mp_machdep.c
--- ia64/ia64/mp_machdep.c 14 Feb 2006 03:40:49 -0000 1.55.2.2
+++ ia64/ia64/mp_machdep.c 23 Aug 2007 18:05:54 -0000
@@ -136,7 +136,7 @@ ia64_ap_startup(void)
mtx_lock_spin(&sched_lock);
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
ia64_set_tpr(0);
Index: ia64/ia64/trap.c
==================================================================RCS file:
/home/ncvs/src/sys/ia64/ia64/trap.c,v
retrieving revision 1.113.2.3
diff -u -p -r1.113.2.3 trap.c
--- ia64/ia64/trap.c 19 Sep 2006 12:38:08 -0000 1.113.2.3
+++ ia64/ia64/trap.c 23 Aug 2007 20:29:30 -0000
@@ -362,7 +362,6 @@ trap(int vector, struct trapframe *tf)
struct thread *td;
uint64_t ucode;
int error, sig, user;
- u_int sticks;
user = TRAPF_USERMODE(tf) ? 1 : 0;
@@ -374,12 +373,11 @@ trap(int vector, struct trapframe *tf)
if (user) {
ia64_set_fpsr(IA64_FPSR_DEFAULT);
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = tf;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
} else {
- sticks = 0; /* XXX bogus -Wuninitialized warning */
KASSERT(cold || td->td_ucred != NULL,
("kernel trap doesn't have ucred"));
#ifdef KDB
@@ -875,7 +873,7 @@ trap(int vector, struct trapframe *tf)
out:
if (user) {
- userret(td, tf, sticks);
+ userret(td, tf);
mtx_assert(&Giant, MA_NOTOWNED);
do_ast(tf);
}
@@ -941,7 +939,6 @@ syscall(struct trapframe *tf)
struct thread *td;
uint64_t *args;
int code, error;
- u_int sticks;
ia64_set_fpsr(IA64_FPSR_DEFAULT);
@@ -954,7 +951,7 @@ syscall(struct trapframe *tf)
td->td_frame = tf;
p = td->td_proc;
- sticks = td->td_sticks;
+ td->td_pticks = 0;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
if (p->p_flag & P_SA)
@@ -1035,7 +1032,7 @@ syscall(struct trapframe *tf)
/*
* Handle reschedule and other end-of-syscall issues
*/
- userret(td, tf, sticks);
+ userret(td, tf);
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code);
Index: kern/init_main.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/init_main.c,v
retrieving revision 1.256.2.5
diff -u -p -r1.256.2.5 init_main.c
--- kern/init_main.c 28 Sep 2006 18:27:01 -0000 1.256.2.5
+++ kern/init_main.c 23 Aug 2007 18:05:54 -0000
@@ -460,11 +460,10 @@ proc0_post(void *dummy __unused)
sx_slock(&allproc_lock);
LIST_FOREACH(p, &allproc, p_list) {
microuptime(&p->p_stats->p_start);
- p->p_rux.rux_runtime.sec = 0;
- p->p_rux.rux_runtime.frac = 0;
+ p->p_rux.rux_runtime = 0;
}
sx_sunlock(&allproc_lock);
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
/*
Index: kern/kern_clock.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/kern_clock.c,v
retrieving revision 1.178.2.4
diff -u -p -r1.178.2.4 kern_clock.c
--- kern/kern_clock.c 20 Feb 2007 22:56:28 -0000 1.178.2.4
+++ kern/kern_clock.c 23 Aug 2007 20:32:25 -0000
@@ -421,7 +421,7 @@ statclock(frame)
*/
if (p->p_flag & P_SA)
thread_statclock(1);
- p->p_rux.rux_uticks++;
+ td->td_uticks++;
if (p->p_nice > NZERO)
cp_time[CP_NICE]++;
else
@@ -441,13 +441,13 @@ statclock(frame)
*/
if ((td->td_pflags & TDP_ITHREAD) ||
td->td_intr_nesting_level >= 2) {
- p->p_rux.rux_iticks++;
+ td->td_iticks++;
cp_time[CP_INTR]++;
} else {
if (p->p_flag & P_SA)
thread_statclock(0);
+ td->td_pticks++;
td->td_sticks++;
- p->p_rux.rux_sticks++;
if (td != PCPU_GET(idlethread))
cp_time[CP_SYS]++;
else
Index: kern/kern_fork.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.252.2.6
diff -u -p -r1.252.2.6 kern_fork.c
--- kern/kern_fork.c 19 Jul 2007 18:46:32 -0000 1.252.2.6
+++ kern/kern_fork.c 23 Aug 2007 18:11:10 -0000
@@ -856,7 +856,7 @@ fork_return(td, frame)
struct trapframe *frame;
{
- userret(td, frame, 0);
+ userret(td, frame);
#ifdef KTRACE
if (KTRPOINT(td, KTR_SYSRET))
ktrsysret(SYS_fork, 0, 0);
Index: kern/kern_proc.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.230.2.5
diff -u -p -r1.230.2.5 kern_proc.c
--- kern/kern_proc.c 29 Sep 2006 07:41:24 -0000 1.230.2.5
+++ kern/kern_proc.c 23 Aug 2007 20:32:25 -0000
@@ -621,7 +621,6 @@ fill_kinfo_proc_only(struct proc *p, str
struct thread *td0;
struct tty *tp;
struct session *sp;
- struct timeval tv;
struct ucred *cred;
struct sigacts *ps;
@@ -692,8 +691,7 @@ fill_kinfo_proc_only(struct proc *p, str
kp->ki_swtime = p->p_swtime;
kp->ki_pid = p->p_pid;
kp->ki_nice = p->p_nice;
- bintime2timeval(&p->p_rux.rux_runtime, &tv);
- kp->ki_runtime = tv.tv_sec * (u_int64_t)1000000 + tv.tv_usec;
+ kp->ki_runtime = cputick2usec(p->p_rux.rux_runtime);
mtx_unlock_spin(&sched_lock);
if ((p->p_sflag & PS_INMEM) && p->p_stats != NULL) {
kp->ki_start = p->p_stats->p_start;
Index: kern/kern_resource.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/kern_resource.c,v
retrieving revision 1.148.2.3
diff -u -p -r1.148.2.3 kern_resource.c
--- kern/kern_resource.c 19 Jul 2007 18:46:32 -0000 1.148.2.3
+++ kern/kern_resource.c 23 Aug 2007 21:25:37 -0000
@@ -694,125 +694,132 @@ getrlimit(td, uap)
}
/*
- * Transform the running time and tick information in proc p into user,
- * system, and interrupt time usage.
+ * Transform the running time and tick information for children of proc p
+ * into user and system time usage.
*/
void
-calcru(p, up, sp)
+calccru(p, up, sp)
struct proc *p;
struct timeval *up;
struct timeval *sp;
{
- struct bintime bt;
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ calcru1(p, &p->p_crux, up, sp);
+}
+
+/*
+ * Transform the running time and tick information in proc p into user
+ * and system time usage. If appropriate, include the current time slice
+ * on this CPU.
+ */
+void
+calcru(struct proc *p, struct timeval *up, struct timeval *sp)
+{
struct rusage_ext rux;
struct thread *td;
- int bt_valid;
+ uint64_t u;
PROC_LOCK_ASSERT(p, MA_OWNED);
mtx_assert(&sched_lock, MA_NOTOWNED);
- bt_valid = 0;
mtx_lock_spin(&sched_lock);
- rux = p->p_rux;
- FOREACH_THREAD_IN_PROC(p, td) {
- if (TD_IS_RUNNING(td)) {
- /*
- * Adjust for the current time slice. This is
- * actually fairly important since the error here is
- * on the order of a time quantum which is much
- * greater than the precision of binuptime().
- */
- KASSERT(td->td_oncpu != NOCPU,
- ("%s: running thread has no CPU", __func__));
- if (!bt_valid) {
- binuptime(&bt);
- bt_valid = 1;
- }
- bintime_add(&rux.rux_runtime, &bt);
- bintime_sub(&rux.rux_runtime,
- &pcpu_find(td->td_oncpu)->pc_switchtime);
- }
+
+ /*
+ * If we are getting stats for the current process, then add in the
+ * stats that this thread has accumulated in its current time slice.
+ * We reset the thread and CPU state as if we had performed a context
+ * switch right here.
+ */
+ if (curthread->td_proc == p) {
+ td = curthread;
+ u = cpu_ticks();
+ p->p_rux.rux_runtime += u - PCPU_GET(switchtime);
+ PCPU_SET(switchtime, u);
+ p->p_rux.rux_uticks += td->td_uticks;
+ td->td_uticks = 0;
+ p->p_rux.rux_iticks += td->td_iticks;
+ td->td_iticks = 0;
+ p->p_rux.rux_sticks += td->td_sticks;
+ td->td_sticks = 0;
}
+ /* Work on a copy of p_rux so we can let go of sched_lock */
+ rux = p->p_rux;
mtx_unlock_spin(&sched_lock);
calcru1(p, &rux, up, sp);
+ /* Update the result from the p_rux copy */
p->p_rux.rux_uu = rux.rux_uu;
p->p_rux.rux_su = rux.rux_su;
- p->p_rux.rux_iu = rux.rux_iu;
-}
-
-void
-calccru(p, up, sp)
- struct proc *p;
- struct timeval *up;
- struct timeval *sp;
-{
-
- PROC_LOCK_ASSERT(p, MA_OWNED);
- calcru1(p, &p->p_crux, up, sp);
+ p->p_rux.rux_tu = rux.rux_tu;
}
static void
-calcru1(p, ruxp, up, sp)
- struct proc *p;
- struct rusage_ext *ruxp;
- struct timeval *up;
- struct timeval *sp;
+calcru1(struct proc *p, struct rusage_ext *ruxp, struct timeval *up,
+ struct timeval *sp)
{
- struct timeval tv;
- /* {user, system, interrupt, total} {ticks, usec}; previous tu: */
- u_int64_t ut, uu, st, su, it, iu, tt, tu, ptu;
+ /* {user, system, interrupt, total} {ticks, usec}: */
+ u_int64_t ut, uu, st, su, it, tt, tu;
ut = ruxp->rux_uticks;
st = ruxp->rux_sticks;
it = ruxp->rux_iticks;
tt = ut + st + it;
if (tt == 0) {
+ /* Avoid divide by zero */
st = 1;
tt = 1;
}
- bintime2timeval(&ruxp->rux_runtime, &tv);
- tu = (u_int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
- ptu = ruxp->rux_uu + ruxp->rux_su + ruxp->rux_iu;
- if (tu < ptu) {
- printf(
-"calcru: runtime went backwards from %ju usec to %ju usec for pid %d
(%s)\n",
- (uintmax_t)ptu, (uintmax_t)tu, p->p_pid, p->p_comm);
- tu = ptu;
- }
+ tu = cputick2usec(ruxp->rux_runtime);
if ((int64_t)tu < 0) {
+ /* XXX: this should be an assert /phk */
printf("calcru: negative runtime of %jd usec for pid %d (%s)\n",
(intmax_t)tu, p->p_pid, p->p_comm);
- tu = ptu;
+ tu = ruxp->rux_tu;
}
- /* Subdivide tu. */
- uu = (tu * ut) / tt;
- su = (tu * st) / tt;
- iu = tu - uu - su;
-
- /* Enforce monotonicity. */
- if (uu < ruxp->rux_uu || su < ruxp->rux_su || iu <
ruxp->rux_iu) {
+ if (tu >= ruxp->rux_tu) {
+ /*
+ * The normal case, time increased.
+ * Enforce monotonicity of bucketed numbers.
+ */
+ uu = (tu * ut) / tt;
if (uu < ruxp->rux_uu)
uu = ruxp->rux_uu;
- else if (uu + ruxp->rux_su + ruxp->rux_iu > tu)
- uu = tu - ruxp->rux_su - ruxp->rux_iu;
- if (st == 0)
+ su = (tu * st) / tt;
+ if (su < ruxp->rux_su)
su = ruxp->rux_su;
- else {
- su = ((tu - uu) * st) / (st + it);
- if (su < ruxp->rux_su)
- su = ruxp->rux_su;
- else if (uu + su + ruxp->rux_iu > tu)
- su = tu - uu - ruxp->rux_iu;
- }
- KASSERT(uu + su + ruxp->rux_iu <= tu,
- ("calcru: monotonisation botch 1"));
- iu = tu - uu - su;
- KASSERT(iu >= ruxp->rux_iu,
- ("calcru: monotonisation botch 2"));
+ } else if (tu + 3 > ruxp->rux_tu || 101 * tu > 100 * ruxp->rux_tu)
{
+ /*
+ * When we calibrate the cputicker, it is not uncommon to
+ * see the presumably fixed frequency increase slightly over
+ * time as a result of thermal stabilization and NTP
+ * discipline (of the reference clock). We therefore ignore
+ * a bit of backwards slop because we expect to catch up
+ * shortly. We use a 3 microsecond limit to catch low
+ * counts and a 1% limit for high counts.
+ */
+ uu = ruxp->rux_uu;
+ su = ruxp->rux_su;
+ tu = ruxp->rux_tu;
+ } else { /* tu < ruxp->rux_tu */
+ /*
+ * What happene here was likely that a laptop, which ran at
+ * a reduced clock frequency at boot, kicked into high gear.
+ * The wisdom of spamming this message in that case is
+ * dubious, but it might also be indicative of something
+ * serious, so lets keep it and hope laptops can be made
+ * more truthful about their CPU speed via ACPI.
+ */
+ printf("calcru: runtime went backwards from %ju usec "
+ "to %ju usec for pid %d (%s)\n",
+ (uintmax_t)ruxp->rux_tu, (uintmax_t)tu,
+ p->p_pid, p->p_comm);
+ uu = (tu * ut) / tt;
+ su = (tu * st) / tt;
}
+
ruxp->rux_uu = uu;
ruxp->rux_su = su;
- ruxp->rux_iu = iu;
+ ruxp->rux_tu = tu;
up->tv_sec = uu / 1000000;
up->tv_usec = uu % 1000000;
@@ -883,13 +890,13 @@ ruadd(ru, rux, ru2, rux2)
register long *ip, *ip2;
register int i;
- bintime_add(&rux->rux_runtime, &rux2->rux_runtime);
+ rux->rux_runtime += rux2->rux_runtime;
rux->rux_uticks += rux2->rux_uticks;
rux->rux_sticks += rux2->rux_sticks;
rux->rux_iticks += rux2->rux_iticks;
rux->rux_uu += rux2->rux_uu;
rux->rux_su += rux2->rux_su;
- rux->rux_iu += rux2->rux_iu;
+ rux->rux_tu += rux2->rux_tu;
if (ru->ru_maxrss < ru2->ru_maxrss)
ru->ru_maxrss = ru2->ru_maxrss;
ip = &ru->ru_first;
Index: kern/kern_synch.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.270.2.6
diff -u -p -r1.270.2.6 kern_synch.c
--- kern/kern_synch.c 6 Jul 2006 08:32:50 -0000 1.270.2.6
+++ kern/kern_synch.c 23 Aug 2007 20:32:25 -0000
@@ -337,7 +337,7 @@ wakeup_one(ident)
void
mi_switch(int flags, struct thread *newtd)
{
- struct bintime new_switchtime;
+ uint64_t new_switchtime;
struct thread *td;
struct proc *p;
@@ -366,9 +366,14 @@ mi_switch(int flags, struct thread *newt
* Compute the amount of time during which the current
* process was running, and add that to its total so far.
*/
- binuptime(&new_switchtime);
- bintime_add(&p->p_rux.rux_runtime, &new_switchtime);
- bintime_sub(&p->p_rux.rux_runtime, PCPU_PTR(switchtime));
+ new_switchtime = cpu_ticks();
+ p->p_rux.rux_runtime += (new_switchtime - PCPU_GET(switchtime));
+ p->p_rux.rux_uticks += td->td_uticks;
+ td->td_uticks = 0;
+ p->p_rux.rux_iticks += td->td_iticks;
+ td->td_iticks = 0;
+ p->p_rux.rux_sticks += td->td_sticks;
+ td->td_sticks = 0;
td->td_generation++; /* bump preempt-detect counter */
@@ -387,7 +392,7 @@ mi_switch(int flags, struct thread *newt
* it reaches the max, arrange to kill the process in ast().
*/
if (p->p_cpulimit != RLIM_INFINITY &&
- p->p_rux.rux_runtime.sec >= p->p_cpulimit) {
+ p->p_rux.rux_runtime >= p->p_cpulimit * cpu_tickrate()) {
p->p_sflag |= PS_XCPU;
td->td_flags |= TDF_ASTPENDING;
}
Index: kern/kern_tc.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/kern_tc.c,v
retrieving revision 1.164
diff -u -p -r1.164 kern_tc.c
--- kern/kern_tc.c 26 Mar 2005 20:04:28 -0000 1.164
+++ kern/kern_tc.c 23 Aug 2007 20:32:25 -0000
@@ -116,6 +116,7 @@ TC_STATS(nsetclock);
#undef TC_STATS
static void tc_windup(void);
+static void cpu_tick_calibrate(int);
static int
sysctl_kern_boottime(SYSCTL_HANDLER_ARGS)
@@ -131,6 +132,7 @@ sysctl_kern_boottime(SYSCTL_HANDLER_ARGS
#endif
return SYSCTL_OUT(req, &boottime, sizeof(boottime));
}
+
/*
* Return the difference between the timehands' counter value now and what
* was when we copied it to the timehands' offset_count.
@@ -363,6 +365,7 @@ tc_setclock(struct timespec *ts)
struct timespec ts2;
struct bintime bt, bt2;
+ cpu_tick_calibrate(1);
nsetclock++;
binuptime(&bt2);
timespec2bintime(ts, &bt);
@@ -379,6 +382,7 @@ tc_setclock(struct timespec *ts)
(intmax_t)ts2.tv_sec, ts2.tv_nsec,
(intmax_t)ts->tv_sec, ts->tv_nsec);
}
+ cpu_tick_calibrate(1);
}
/*
@@ -475,8 +479,8 @@ tc_windup(void)
* x = a * 2^32 / 10^9 = a * 4.294967296
*
* The range of th_adjustment is +/- 5000PPM so inside a 64bit int
- * we can only multiply by about 850 without overflowing, but that
- * leaves suitably precise fractions for multiply before divide.
+ * we can only multiply by about 850 without overflowing, that
+ * leaves no suitably precise fractions for multiply before divide.
*
* Divide before multiply with a fraction of 2199/512 results in a
* systematic undercompensation of 10PPM of th_adjustment. On a
@@ -749,11 +753,16 @@ void
tc_ticktock(void)
{
static int count;
+ static time_t last_calib;
if (++count < tc_tick)
return;
count = 0;
tc_windup();
+ if (time_uptime != last_calib && !(time_uptime & 0xf)) {
+ cpu_tick_calibrate(0);
+ last_calib = time_uptime;
+ }
}
static void
@@ -782,3 +791,143 @@ inittimecounter(void *dummy)
}
SYSINIT(timecounter, SI_SUB_CLOCKS, SI_ORDER_SECOND, inittimecounter, NULL)
+
+/* Cpu tick handling -------------------------------------------------*/
+
+static int cpu_tick_variable;
+static uint64_t cpu_tick_frequency;
+
+static
+uint64_t
+tc_cpu_ticks(void)
+{
+ static uint64_t base;
+ static unsigned last;
+ unsigned u;
+ struct timecounter *tc;
+
+ tc = timehands->th_counter;
+ u = tc->tc_get_timecount(tc) & tc->tc_counter_mask;
+ if (u < last)
+ base += tc->tc_counter_mask + 1;
+ last = u;
+ return (u + base);
+}
+
+/*
+ * This function gets called ever 16 seconds on only one designated
+ * CPU in the system from hardclock() via tc_ticktock().
+ *
+ * Whenever the real time clock is stepped we get called with reset=1
+ * to make sure we handle suspend/resume and similar events correctly.
+ */
+
+static void
+cpu_tick_calibrate(int reset)
+{
+ static uint64_t c_last;
+ uint64_t c_this, c_delta;
+ static struct bintime t_last;
+ struct bintime t_this, t_delta;
+
+ if (reset) {
+ /* The clock was stepped, abort & reset */
+ t_last.sec = 0;
+ return;
+ }
+
+ /* we don't calibrate fixed rate cputicks */
+ if (!cpu_tick_variable)
+ return;
+
+ getbinuptime(&t_this);
+ c_this = cpu_ticks();
+ if (t_last.sec != 0) {
+ c_delta = c_this - c_last;
+ t_delta = t_this;
+ bintime_sub(&t_delta, &t_last);
+ if (0 && bootverbose) {
+ struct timespec ts;
+ bintime2timespec(&t_delta, &ts);
+ printf("%ju %ju.%016jx %ju.%09ju",
+ (uintmax_t)c_delta >> 4,
+ (uintmax_t)t_delta.sec, (uintmax_t)t_delta.frac,
+ (uintmax_t)ts.tv_sec, (uintmax_t)ts.tv_nsec);
+ }
+ /*
+ * Validate that 16 +/- 1/256 seconds passed.
+ * After division by 16 this gives us a precision of
+ * roughly 250PPM which is sufficient
+ */
+ if (t_delta.sec > 16 || (
+ t_delta.sec == 16 && t_delta.frac >= (0x01LL << 56))) {
+ /* too long */
+ if (0 && bootverbose)
+ printf("\ttoo long\n");
+ } else if (t_delta.sec < 15 ||
+ (t_delta.sec == 15 && t_delta.frac <= (0xffLL << 56))) {
+ /* too short */
+ if (0 && bootverbose)
+ printf("\ttoo short\n");
+ } else {
+ /* just right */
+ c_delta >>= 4;
+ if (c_delta > cpu_tick_frequency) {
+ if (0 && bootverbose)
+ printf("\thigher\n");
+ cpu_tick_frequency = c_delta;
+ } else {
+ if (0 && bootverbose)
+ printf("\tlower\n");
+ }
+ }
+ }
+ c_last = c_this;
+ t_last = t_this;
+}
+
+void
+set_cputicker(cpu_tick_f *func, uint64_t freq, unsigned var)
+{
+
+ if (func == NULL) {
+ cpu_ticks = tc_cpu_ticks;
+ } else {
+ cpu_tick_frequency = freq;
+ cpu_tick_variable = var;
+ cpu_ticks = func;
+ }
+}
+
+uint64_t
+cpu_tickrate(void)
+{
+
+ if (cpu_ticks == tc_cpu_ticks)
+ return (tc_getfrequency());
+ return (cpu_tick_frequency);
+}
+
+/*
+ * We need to be slightly careful converting cputicks to microseconds.
+ * There is plenty of margin in 64 bits of microseconds (half a million
+ * years) and in 64 bits at 4 GHz (146 years), but if we do a multiply
+ * before divide conversion (to retain precision) we find that the
+ * margin shrinks to 1.5 hours (one millionth of 146y).
+ * With a three prong approach we never loose significant bits, no
+ * matter what the cputick rate and length of timeinterval is.
+ */
+
+uint64_t
+cputick2usec(uint64_t tick)
+{
+
+ if (tick > 18446744073709551LL) /* floor(2^64 / 1000) */
+ return (tick / (cpu_tickrate() / 1000000LL));
+ else if (tick > 18446744073709LL) /* floor(2^64 / 1000000) */
+ return ((tick * 1000LL) / (cpu_tickrate() / 1000LL));
+ else
+ return ((tick * 1000000LL) / cpu_tickrate());
+}
+
+cpu_tick_f *cpu_ticks = tc_cpu_ticks;
Index: kern/kern_thread.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/kern_thread.c,v
retrieving revision 1.216.2.6
diff -u -p -r1.216.2.6 kern_thread.c
--- kern/kern_thread.c 2 Sep 2006 17:29:57 -0000 1.216.2.6
+++ kern/kern_thread.c 23 Aug 2007 18:05:54 -0000
@@ -448,7 +448,7 @@ thread_free(struct thread *td)
void
thread_exit(void)
{
- struct bintime new_switchtime;
+ uint64_t new_switchtime;
struct thread *td;
struct proc *p;
struct ksegrp *kg;
@@ -488,13 +488,14 @@ thread_exit(void)
/*
* The thread is exiting. scheduler can release its stuff
* and collect stats etc.
+ * XXX this is not very right, since PROC_UNLOCK may still
+ * need scheduler stuff.
*/
sched_thread_exit(td);
/* Do the same timestamp bookkeeping that mi_switch() would do. */
- binuptime(&new_switchtime);
- bintime_add(&p->p_rux.rux_runtime, &new_switchtime);
- bintime_sub(&p->p_rux.rux_runtime, PCPU_PTR(switchtime));
+ new_switchtime = cpu_ticks();
+ p->p_rux.rux_runtime += (new_switchtime - PCPU_GET(switchtime));
PCPU_SET(switchtime, new_switchtime);
PCPU_SET(switchticks, ticks);
cnt.v_swtch++;
Index: kern/subr_trap.c
==================================================================RCS file:
/home/ncvs/src/sys/kern/subr_trap.c,v
retrieving revision 1.281.2.1
diff -u -p -r1.281.2.1 subr_trap.c
--- kern/subr_trap.c 6 Sep 2006 21:43:59 -0000 1.281.2.1
+++ kern/subr_trap.c 23 Aug 2007 18:11:10 -0000
@@ -74,10 +74,7 @@ __FBSDID("$FreeBSD: src/sys/kern/subr_tr
* MPSAFE
*/
void
-userret(td, frame, oticks)
- struct thread *td;
- struct trapframe *frame;
- u_int oticks;
+userret(struct thread *td, struct trapframe *frame)
{
struct proc *p = td->td_proc;
@@ -127,10 +124,8 @@ userret(td, frame, oticks)
* Charge system time if profiling.
*/
if (p->p_flag & P_PROFIL) {
- quad_t ticks;
- ticks = td->td_sticks - oticks;
- addupc_task(td, TRAPF_PC(frame), (u_int)ticks * psratio);
+ addupc_task(td, TRAPF_PC(frame), td->td_pticks * psratio);
}
/*
@@ -153,7 +148,6 @@ ast(struct trapframe *framep)
struct proc *p;
struct ksegrp *kg;
struct rlimit rlim;
- u_int sticks;
int sflag;
int flags;
int sig;
@@ -172,7 +166,7 @@ ast(struct trapframe *framep)
mtx_assert(&Giant, MA_NOTOWNED);
mtx_assert(&sched_lock, MA_NOTOWNED);
td->td_frame = framep;
- sticks = td->td_sticks;
+ td->td_pticks = 0;
if ((p->p_flag & P_SA) && (td->td_mailbox == NULL))
thread_user_enter(td);
@@ -234,7 +228,7 @@ ast(struct trapframe *framep)
PROC_LOCK(p);
lim_rlimit(p, RLIMIT_CPU, &rlim);
mtx_lock_spin(&sched_lock);
- if (p->p_rux.rux_runtime.sec >= rlim.rlim_max) {
+ if (p->p_rux.rux_runtime >= rlim.rlim_max * cpu_tickrate()) {
mtx_unlock_spin(&sched_lock);
killproc(p, "exceeded maximum CPU limit");
} else {
@@ -272,6 +266,6 @@ ast(struct trapframe *framep)
PROC_UNLOCK(p);
}
- userret(td, framep, sticks);
+ userret(td, framep);
mtx_assert(&Giant, MA_NOTOWNED);
}
Index: powerpc/powerpc/trap.c
==================================================================RCS file:
/home/ncvs/src/sys/powerpc/powerpc/trap.c,v
retrieving revision 1.54.2.3
diff -u -p -r1.54.2.3 trap.c
--- powerpc/powerpc/trap.c 19 Sep 2006 12:38:08 -0000 1.54.2.3
+++ powerpc/powerpc/trap.c 23 Aug 2007 20:28:18 -0000
@@ -146,7 +146,7 @@ trap(struct trapframe *frame)
struct thread *td;
struct proc *p;
int sig, type, user;
- u_int sticks, ucode;
+ u_int ucode;
PCPU_LAZY_INC(cnt.v_trap);
@@ -156,13 +156,12 @@ trap(struct trapframe *frame)
type = ucode = frame->exc;
sig = 0;
user = frame->srr1 & PSL_PR;
- sticks = 0;
CTR3(KTR_TRAP, "trap: %s type=%s (%s)", p->p_comm,
trapname(type), user ? "user" : "kernel");
if (user) {
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = frame;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -260,7 +259,7 @@ trap(struct trapframe *frame)
trapsignal(td, sig, ucode);
}
- userret(td, frame, sticks);
+ userret(td, frame);
mtx_assert(&Giant, MA_NOTOWNED);
}
Index: sparc64/sparc64/mp_machdep.c
==================================================================RCS file:
/home/ncvs/src/sys/sparc64/sparc64/mp_machdep.c,v
retrieving revision 1.29.2.2
diff -u -p -r1.29.2.2 mp_machdep.c
--- sparc64/sparc64/mp_machdep.c 4 Sep 2006 18:28:32 -0000 1.29.2.2
+++ sparc64/sparc64/mp_machdep.c 23 Aug 2007 18:05:54 -0000
@@ -363,7 +363,7 @@ cpu_mp_bootstrap(struct pcpu *pc)
/* ok, now grab sched_lock and enter the scheduler */
mtx_lock_spin(&sched_lock);
spinlock_exit();
- binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchtime, cpu_ticks());
PCPU_SET(switchticks, ticks);
cpu_throw(NULL, choosethread()); /* doesn't return */
}
Index: sparc64/sparc64/tick.c
==================================================================RCS file:
/home/ncvs/src/sys/sparc64/sparc64/tick.c,v
retrieving revision 1.16.2.1
diff -u -p -r1.16.2.1 tick.c
--- sparc64/sparc64/tick.c 31 Mar 2006 23:38:29 -0000 1.16.2.1
+++ sparc64/sparc64/tick.c 23 Aug 2007 20:32:25 -0000
@@ -64,6 +64,13 @@ SYSCTL_INT(_machdep_tick, OID_AUTO, adju
static void tick_hardclock(struct clockframe *);
+static uint64_t
+tick_cputicks(void)
+{
+
+ return (rd(tick));
+}
+
void
cpu_initclocks(void)
{
@@ -148,6 +155,8 @@ tick_init(u_long clock)
* handled.
*/
tick_stop();
+
+ set_cputicker(tick_cputicks, tick_freq, 0);
}
void
Index: sparc64/sparc64/trap.c
==================================================================RCS file:
/home/ncvs/src/sys/sparc64/sparc64/trap.c,v
retrieving revision 1.74.2.2
diff -u -p -r1.74.2.2 trap.c
--- sparc64/sparc64/trap.c 29 Jan 2007 21:32:18 -0000 1.74.2.2
+++ sparc64/sparc64/trap.c 23 Aug 2007 18:11:10 -0000
@@ -234,7 +234,6 @@ trap(struct trapframe *tf)
{
struct thread *td;
struct proc *p;
- u_int sticks;
int error;
int sig;
@@ -251,7 +250,7 @@ trap(struct trapframe *tf)
KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
p = td->td_proc;
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = tf;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -291,7 +290,7 @@ trap(struct trapframe *tf)
trapsignal(td, sig, tf->tf_type);
}
- userret(td, tf, sticks);
+ userret(td, tf);
mtx_assert(&Giant, MA_NOTOWNED);
} else {
KASSERT((tf->tf_type & T_KERNEL) != 0,
@@ -500,7 +499,6 @@ syscall(struct trapframe *tf)
register_t args[8];
register_t *argp;
struct proc *p;
- u_int sticks;
u_long code;
u_long tpc;
int reg;
@@ -521,7 +519,7 @@ syscall(struct trapframe *tf)
reg = 0;
regcnt = REG_MAXARGS;
- sticks = td->td_sticks;
+ td->td_pticks = 0;
td->td_frame = tf;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
@@ -646,7 +644,7 @@ syscall(struct trapframe *tf)
/*
* Handle reschedule and other end-of-syscall issues
*/
- userret(td, tf, sticks);
+ userret(td, tf);
#ifdef KTRACE
if (KTRPOINT(td, KTR_SYSRET))
Index: sys/pcpu.h
==================================================================RCS file:
/home/ncvs/src/sys/sys/pcpu.h,v
retrieving revision 1.16
diff -u -p -r1.16 pcpu.h
--- sys/pcpu.h 26 Apr 2005 17:07:40 -0000 1.16
+++ sys/pcpu.h 23 Aug 2007 18:05:54 -0000
@@ -60,7 +60,7 @@ struct pcpu {
struct thread *pc_fpcurthread; /* Fp state owner */
struct thread *pc_deadthread; /* Zombie thread or NULL */
struct pcb *pc_curpcb; /* Current pcb */
- struct bintime pc_switchtime;
+ uint64_t pc_switchtime;
int pc_switchticks;
u_int pc_cpuid; /* This cpu number */
cpumask_t pc_cpumask; /* This cpu mask */
Index: sys/proc.h
==================================================================RCS file:
/home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.432.2.10
diff -u -p -r1.432.2.10 proc.h
--- sys/proc.h 11 Jun 2007 11:27:04 -0000 1.432.2.10
+++ sys/proc.h 23 Aug 2007 21:25:37 -0000
@@ -278,7 +278,10 @@ struct thread {
struct ucred *td_ucred; /* (k) Reference to credentials. */
struct thread *td_standin; /* (k + a) Use this for an upcall. */
struct kse_upcall *td_upcall; /* (k + j) Upcall structure. */
- u_int64_t td_sticks; /* (k) Statclock hits in system mode. */
+ u_int td_pticks; /* (k) Statclock hits for profiling */
+ u_int td_sticks; /* (k) Statclock hits in system mode. */
+ u_int td_iticks; /* (k) Statclock hits in intr mode. */
+ u_int td_uticks; /* (k) Statclock hits in user mode. */
u_int td_uuticks; /* (k) Statclock hits (usr), for UTS. */
u_int td_usticks; /* (k) Statclock hits (sys), for UTS. */
int td_intrval; /* (j) Return value of TDF_INTERRUPT. */
@@ -502,13 +505,13 @@ struct ksegrp {
* Locking: (cj) means (j) for p_rux and (c) for p_crux.
*/
struct rusage_ext {
- struct bintime rux_runtime; /* (cj) Real time. */
+ u_int64_t rux_runtime; /* (cj) Real time. */
u_int64_t rux_uticks; /* (cj) Statclock hits in user mode. */
u_int64_t rux_sticks; /* (cj) Statclock hits in sys mode. */
u_int64_t rux_iticks; /* (cj) Statclock hits in intr mode. */
u_int64_t rux_uu; /* (c) Previous user time in usec. */
u_int64_t rux_su; /* (c) Previous sys time in usec. */
- u_int64_t rux_iu; /* (c) Previous intr time in usec. */
+ u_int64_t rux_tu; /* (c) Previous total time in usec. */
};
/*
@@ -910,7 +913,7 @@ extern void (*cpu_idle_hook)(void); /* H
void cpu_switch(struct thread *old, struct thread *new);
void cpu_throw(struct thread *old, struct thread *new) __dead2;
void unsleep(struct thread *);
-void userret(struct thread *, struct trapframe *, u_int);
+void userret(struct thread *, struct trapframe *);
void cpu_exit(struct thread *);
void exit1(struct thread *, int) __dead2;
Index: sys/systm.h
==================================================================RCS file:
/home/ncvs/src/sys/sys/systm.h,v
retrieving revision 1.234.2.6
diff -u -p -r1.234.2.6 systm.h
--- sys/systm.h 18 Jun 2007 22:44:59 -0000 1.234.2.6
+++ sys/systm.h 23 Aug 2007 20:32:25 -0000
@@ -240,6 +240,12 @@ int setenv(const char *name, const char
int unsetenv(const char *name);
int testenv(const char *name);
+typedef uint64_t (cpu_tick_f)(void);
+void set_cputicker(cpu_tick_f *func, uint64_t freq, unsigned var);
+extern cpu_tick_f *cpu_ticks;
+uint64_t cpu_tickrate(void);
+uint64_t cputick2usec(uint64_t tick);
+
#ifdef APM_FIXUP_CALLTODO
struct timeval;
void adjust_timeout_calltodo(struct timeval *time_change);