Rejig the code to figure out estcpu and work out how long a KSEGRP has been

idle. What was there before was surprisingly ALMOST correct.

Peter and I fried our brains on this for a couple of hours figuring out
what this actually means in the context of multiple threads.

Reviewed by:	peter@freebsd.org
This commit is contained in:
julian 2002-08-30 00:25:49 +00:00
parent 3968b50cd2
commit b085f4e6d2
3 changed files with 30 additions and 18 deletions

View File

@ -156,8 +156,10 @@ retry:
} else { } else {
/* Simulate runq_choose() having returned the idle thread */ /* Simulate runq_choose() having returned the idle thread */
td = PCPU_GET(idlethread); td = PCPU_GET(idlethread);
ke = td->td_kse;
CTR1(KTR_RUNQ, "choosethread: td=%p (idle)", td); CTR1(KTR_RUNQ, "choosethread: td=%p (idle)", td);
} }
ke->ke_flags |= KEF_DIDRUN;
if (panicstr && ((td->td_proc->p_flag & P_SYSTEM) == 0 && if (panicstr && ((td->td_proc->p_flag & P_SYSTEM) == 0 &&
(td->td_flags & TDF_INPANIC) == 0)) (td->td_flags & TDF_INPANIC) == 0))
goto retry; goto retry;

View File

@ -281,17 +281,16 @@ schedcpu(arg)
* The kse slptimes are not touched in wakeup * The kse slptimes are not touched in wakeup
* because the thread may not HAVE a KSE. * because the thread may not HAVE a KSE.
*/ */
if ((ke->ke_state == KES_ONRUNQ) || if (ke->ke_state == KES_ONRUNQ) {
((ke->ke_state == KES_THREAD) &&
(ke->ke_thread->td_state == TDS_RUNNING))) {
ke->ke_slptime = 0;
awake = 1; awake = 1;
} else { ke->ke_flags &= ~KEF_DIDRUN;
/* XXXKSE } else if ((ke->ke_state == KES_THREAD) &&
* This is probably a pointless (ke->ke_thread->td_state == TDS_RUNNING)) {
* statistic in a KSE world. awake = 1;
*/ /* Do not clear KEF_DIDRUN */
ke->ke_slptime++; } else if (ke->ke_flags & KEF_DIDRUN) {
awake = 1;
ke->ke_flags &= ~KEF_DIDRUN;
} }
/* /*
@ -306,10 +305,8 @@ schedcpu(arg)
* stop recalculating its priority until * stop recalculating its priority until
* it wakes up. * it wakes up.
*/ */
if (ke->ke_slptime > 1) { if (ke->ke_cpticks == 0)
continue; continue;
}
#if (FSHIFT >= CCPU_SHIFT) #if (FSHIFT >= CCPU_SHIFT)
ke->ke_pctcpu += (realstathz == 100) ? ke->ke_pctcpu += (realstathz == 100) ?
((fixpt_t) ke->ke_cpticks) << ((fixpt_t) ke->ke_cpticks) <<
@ -327,11 +324,25 @@ schedcpu(arg)
* If there are ANY running threads in this KSEGRP, * If there are ANY running threads in this KSEGRP,
* then don't count it as sleeping. * then don't count it as sleeping.
*/ */
if (awake == 0) { if (awake) {
kg->kg_slptime++; if (kg->kg_slptime > 1) {
} else { /*
* In an ideal world, this should not
* happen, because whoever woke us
* up from the long sleep should have
* unwound the slptime and reset our
* priority before we run at the stale
* priority. Should KASSERT at some
* point when all the cases are fixed.
*/
updatepri(kg);
}
kg->kg_slptime = 0; kg->kg_slptime = 0;
} else {
kg->kg_slptime++;
} }
if (kg->kg_slptime > 1)
continue;
kg->kg_estcpu = decay_cpu(loadfac, kg->kg_estcpu); kg->kg_estcpu = decay_cpu(loadfac, kg->kg_estcpu);
resetpriority(kg); resetpriority(kg);
FOREACH_THREAD_IN_GROUP(kg, td) { FOREACH_THREAD_IN_GROUP(kg, td) {
@ -508,7 +519,6 @@ msleep(ident, mtx, priority, wmesg, timo)
td->td_wchan = ident; td->td_wchan = ident;
td->td_wmesg = wmesg; td->td_wmesg = wmesg;
td->td_kse->ke_slptime = 0; /* XXXKSE */
td->td_ksegrp->kg_slptime = 0; td->td_ksegrp->kg_slptime = 0;
td->td_priority = priority & PRIMASK; td->td_priority = priority & PRIMASK;
CTR5(KTR_PROC, "msleep: thread %p (pid %d, %s) on %s (%p)", CTR5(KTR_PROC, "msleep: thread %p (pid %d, %s) on %s (%p)",

View File

@ -364,7 +364,6 @@ struct kse {
u_int64_t ke_sticks; /* (j) Statclock hits in system mode. */ u_int64_t ke_sticks; /* (j) Statclock hits in system mode. */
u_int64_t ke_iticks; /* (j) Statclock hits in intr. */ u_int64_t ke_iticks; /* (j) Statclock hits in intr. */
u_char ke_oncpu; /* (j) Which cpu we are on. */ u_char ke_oncpu; /* (j) Which cpu we are on. */
u_int ke_slptime; /* (j) Time since last idle. */
char ke_rqindex; /* (j) Run queue index. */ char ke_rqindex; /* (j) Run queue index. */
enum { enum {
KES_IDLE = 0x10, KES_IDLE = 0x10,
@ -396,6 +395,7 @@ struct kse {
#define KEF_USER 0x00200 /* Process is not officially in the kernel */ #define KEF_USER 0x00200 /* Process is not officially in the kernel */
#define KEF_ASTPENDING 0x00400 /* KSE has a pending ast. */ #define KEF_ASTPENDING 0x00400 /* KSE has a pending ast. */
#define KEF_NEEDRESCHED 0x00800 /* Process needs to yield. */ #define KEF_NEEDRESCHED 0x00800 /* Process needs to yield. */
#define KEF_DIDRUN 0x02000 /* KSE actually ran. */
/* /*
* (*) A bound KSE with a bound thread in a KSE process may be lent to * (*) A bound KSE with a bound thread in a KSE process may be lent to