diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-06-07 21:20:03 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-06-07 21:20:03 +0000 |
commit | 1001fef5168442fee0d557002fbdd7ba550de37a (patch) | |
tree | f99fe4bd8ee8c15b32361356e5947afecdc6a067 /sys/kern | |
parent | dd21fd69b0521dc635283985655bf473c61a98ea (diff) |
Change addupc_intr to not use fuswintr and suswintr to update the profiling
info. Since we only use it to profile processes in user mode and there
is no way to get back user mode without going past the AST that will
write out the profiling info in a context where copyout works.
Sitting in my tree for ages.
Reviewed and with some suggestions from nordin@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_clock.c | 4 | ||||
-rw-r--r-- | sys/kern/subr_prof.c | 49 |
2 files changed, 16 insertions, 37 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 847e6352f0e..dd83909ea44 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_clock.c,v 1.36 2002/06/07 08:16:26 nordin Exp $ */ +/* $OpenBSD: kern_clock.c,v 1.37 2002/06/07 21:20:02 art Exp $ */ /* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */ /*- @@ -861,7 +861,7 @@ statclock(frame) if (CLKF_USERMODE(frame)) { p = curproc; if (p->p_flag & P_PROFIL) - addupc_intr(p, CLKF_PC(frame), 1); + addupc_intr(p, CLKF_PC(frame)); if (--pscnt > 0) return; /* diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index a18c39c2df1..ff8160908a5 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_prof.c,v 1.9 2001/11/06 19:53:20 miod Exp $ */ +/* $OpenBSD: subr_prof.c,v 1.10 2002/06/07 21:20:02 art Exp $ */ /* $NetBSD: subr_prof.c,v 1.12 1996/04/22 01:38:50 christos Exp $ */ /*- @@ -198,55 +198,34 @@ sys_profil(p, v, retval) /* * Collect user-level profiling statistics; called on a profiling tick, * when a process is running in user-mode. This routine may be called - * from an interrupt context. We try to update the user profiling buffers - * cheaply with fuswintr() and suswintr(). If that fails, we revert to - * an AST that will vector us to trap() with a context in which copyin - * and copyout will work. Trap will then call addupc_task(). - * - * Note that we may (rarely) not get around to the AST soon enough, and - * lose profile ticks when the next tick overwrites this one, but in this - * case the system is overloaded and the profile is probably already - * inaccurate. + * from an interrupt context. Schedule and AST that will vector us to + * trap() with a context in which copyin and copyout will work. + * Trap will then call addupc_task(). */ void -addupc_intr(p, pc, ticks) - register struct proc *p; - register u_long pc; - u_int ticks; +addupc_intr(struct proc *p, u_long pc) { - register struct uprof *prof; - register caddr_t addr; - register u_int i; - register int v; + struct uprof *prof; - if (ticks == 0) - return; prof = &p->p_stats->p_prof; - if (pc < prof->pr_off || - (i = PC_TO_INDEX(pc, prof)) >= prof->pr_size) + if (pc < prof->pr_off || PC_TO_INDEX(pc, prof) >= prof->pr_size) return; /* out of range; ignore */ - addr = prof->pr_base + i; - if ((v = fuswintr(addr)) == -1 || suswintr(addr, v + ticks) == -1) { - prof->pr_addr = pc; - prof->pr_ticks = ticks; - need_proftick(p); - } + prof->pr_addr = pc; + need_proftick(p); } + /* * Much like before, but we can afford to take faults here. If the * update fails, we simply turn off profiling. */ void -addupc_task(p, pc, ticks) - register struct proc *p; - register u_long pc; - u_int ticks; +addupc_task(struct proc *p, u_long pc, u_int ticks) { - register struct uprof *prof; - register caddr_t addr; - register u_int i; + struct uprof *prof; + caddr_t addr; + u_int i; u_short v; /* Testing P_PROFIL may be unnecessary, but is certainly safe. */ |