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 Elischer 2002-08-30 00:25:49 +00:00
parent c34fd0a79a
commit 472be95807
3 changed files with 30 additions and 18 deletions

View File

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

View File

@ -281,17 +281,16 @@ schedcpu(arg)
* The kse slptimes are not touched in wakeup
* because the thread may not HAVE a KSE.
*/
if ((ke->ke_state == KES_ONRUNQ) ||
((ke->ke_state == KES_THREAD) &&
(ke->ke_thread->td_state == TDS_RUNNING))) {
ke->ke_slptime = 0;
if (ke->ke_state == KES_ONRUNQ) {
awake = 1;
} else {
/* XXXKSE
* This is probably a pointless
* statistic in a KSE world.
*/
ke->ke_slptime++;
ke->ke_flags &= ~KEF_DIDRUN;
} else if ((ke->ke_state == KES_THREAD) &&
(ke->ke_thread->td_state == TDS_RUNNING)) {
awake = 1;
/* Do not clear KEF_DIDRUN */
} 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
* it wakes up.
*/
if (ke->ke_slptime > 1) {
if (ke->ke_cpticks == 0)
continue;
}
#if (FSHIFT >= CCPU_SHIFT)
ke->ke_pctcpu += (realstathz == 100) ?
((fixpt_t) ke->ke_cpticks) <<
@ -327,11 +324,25 @@ schedcpu(arg)
* If there are ANY running threads in this KSEGRP,
* then don't count it as sleeping.
*/
if (awake == 0) {
kg->kg_slptime++;
} else {
if (awake) {
if (kg->kg_slptime > 1) {
/*
* 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;
} else {
kg->kg_slptime++;
}
if (kg->kg_slptime > 1)
continue;
kg->kg_estcpu = decay_cpu(loadfac, kg->kg_estcpu);
resetpriority(kg);
FOREACH_THREAD_IN_GROUP(kg, td) {
@ -508,7 +519,6 @@ msleep(ident, mtx, priority, wmesg, timo)
td->td_wchan = ident;
td->td_wmesg = wmesg;
td->td_kse->ke_slptime = 0; /* XXXKSE */
td->td_ksegrp->kg_slptime = 0;
td->td_priority = priority & PRIMASK;
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_iticks; /* (j) Statclock hits in intr. */
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. */
enum {
KES_IDLE = 0x10,
@ -396,6 +395,7 @@ struct kse {
#define KEF_USER 0x00200 /* Process is not officially in the kernel */
#define KEF_ASTPENDING 0x00400 /* KSE has a pending ast. */
#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