diff options
Diffstat (limited to 'sys/kern/kern_clock.c')
-rw-r--r-- | sys/kern/kern_clock.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index c5e1b4a..ab2c9ee 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -320,6 +320,10 @@ startprofclock(p) * cover psdiv, etc. as well. */ mtx_lock_spin(&sched_lock); + if (p->p_sflag & PS_STOPPROF) { + mtx_unlock_spin(&sched_lock); + return; + } if ((p->p_sflag & PS_PROFIL) == 0) { p->p_sflag |= PS_PROFIL; if (++profprocs == 1 && stathz != 0) { @@ -341,9 +345,19 @@ stopprofclock(p) { int s; + PROC_LOCK_ASSERT(p, MA_OWNED); + +retry: mtx_lock_spin(&sched_lock); if (p->p_sflag & PS_PROFIL) { - p->p_sflag &= ~PS_PROFIL; + if (p->p_profthreads) { + p->p_sflag |= PS_STOPPROF; + mtx_unlock_spin(&sched_lock); + msleep(&p->p_profthreads, &p->p_mtx, PPAUSE, + "stopprof", NULL); + goto retry; + } + p->p_sflag &= ~(PS_PROFIL|PS_STOPPROF); if (--profprocs == 0 && stathz != 0) { s = splstatclock(); psdiv = pscnt = 1; @@ -363,10 +377,7 @@ stopprofclock(p) * this function's relationship to statclock. */ void -statclock_process(ke, pc, user) - struct kse *ke; - register_t pc; - int user; +statclock_process(struct thread *td, register_t pc, int user) { #ifdef GPROF struct gmonparam *g; @@ -376,27 +387,31 @@ statclock_process(ke, pc, user) long rss; struct rusage *ru; struct vmspace *vm; - struct proc *p = ke->ke_proc; - struct thread *td = ke->ke_thread; /* current thread */ + struct proc *p = td->td_proc; - 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 (p->p_sflag & PS_PROFIL) { + /* Only when thread is not in transition */ + if (!(td->td_flags & TDF_UPCALLING)) + addupc_intr(td, pc, 1); + } if (pscnt < psdiv) return; /* * Charge the time as appropriate. */ if (p->p_flag & P_KSES) - thread_add_ticks_intr(1, 1); - ke->ke_uticks++; - if (ke->ke_ksegrp->kg_nice > NZERO) + thread_statclock(1); + /* + td->td_uticks++; + */ + p->p_uticks++; + if (td->td_ksegrp->kg_nice > NZERO) cp_time[CP_NICE]++; else cp_time[CP_USER]++; @@ -429,12 +444,16 @@ statclock_process(ke, pc, user) * in ``non-process'' (i.e., interrupt) work. */ if ((td->td_ithd != NULL) || td->td_intr_nesting_level >= 2) { - ke->ke_iticks++; + p->p_iticks++; + /* + td->td_iticks++; + */ cp_time[CP_INTR]++; } else { if (p->p_flag & P_KSES) - thread_add_ticks_intr(0, 1); - ke->ke_sticks++; + thread_statclock(0); + td->td_sticks++; + p->p_sticks++; if (p != PCPU_GET(idlethread)->td_proc) cp_time[CP_SYS]++; else @@ -442,7 +461,7 @@ statclock_process(ke, pc, user) } } - sched_clock(ke->ke_thread); + sched_clock(td); /* Update resource usage integrals and maximums. */ if ((pstats = p->p_stats) != NULL && @@ -472,7 +491,7 @@ statclock(frame) mtx_lock_spin_flags(&sched_lock, MTX_QUIET); if (--pscnt == 0) pscnt = psdiv; - statclock_process(curthread->td_kse, CLKF_PC(frame), CLKF_USERMODE(frame)); + statclock_process(curthread, CLKF_PC(frame), CLKF_USERMODE(frame)); mtx_unlock_spin_flags(&sched_lock, MTX_QUIET); } |