From owner-freebsd-stable@FreeBSD.ORG Fri Aug 24 02:23:15 2007 Return-Path: Delivered-To: stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CC29E16A418 for ; Fri, 24 Aug 2007 02:23:15 +0000 (UTC) (envelope-from obrien@NUXI.com) Received: from dragon.nuxi.org (trang.nuxi.org [74.95.12.85]) by mx1.freebsd.org (Postfix) with ESMTP id 7C06113C45A for ; Fri, 24 Aug 2007 02:23:15 +0000 (UTC) (envelope-from obrien@NUXI.com) Received: from dragon.nuxi.org (obrien@localhost [127.0.0.1]) by dragon.nuxi.org (8.14.1/8.14.1) with ESMTP id l7O1xvJ6017675 for ; Thu, 23 Aug 2007 19:00:02 -0700 (PDT) (envelope-from obrien@dragon.nuxi.org) Received: (from obrien@localhost) by dragon.nuxi.org (8.14.1/8.14.1/Submit) id l7O1xv9Y017674 for stable@freebsd.org; Thu, 23 Aug 2007 18:59:57 -0700 (PDT) (envelope-from obrien) Date: Thu, 23 Aug 2007 18:59:57 -0700 From: "David O'Brien" To: stable@freebsd.org Message-ID: <20070824015956.GA17604@dragon.NUXI.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Operating-System: FreeBSD 7.0-CURRENT Organization: The NUXI BSD Group X-Pgp-Rsa-Fingerprint: B7 4D 3E E9 11 39 5F A3 90 76 5D 69 58 D9 98 7A X-Pgp-Rsa-Keyid: 1024/34F9F9D5 User-Agent: Mutt/1.5.11 Cc: Subject: MFC 7.0 calcru changes X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: obrien@freebsd.org List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 24 Aug 2007 02:23:15 -0000 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);