diff options
author | julian <julian@FreeBSD.org> | 2002-08-30 00:25:49 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 2002-08-30 00:25:49 +0000 |
commit | b085f4e6d284cf69ff73ce1640a38c562547f8bc (patch) | |
tree | f07519d2ea07cb1772f86114bdfc24a9cc5a7540 | |
parent | 3968b50cd269ef90a4ee7fe533933d211ed7062a (diff) | |
download | FreeBSD-src-b085f4e6d284cf69ff73ce1640a38c562547f8bc.zip FreeBSD-src-b085f4e6d284cf69ff73ce1640a38c562547f8bc.tar.gz |
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
-rw-r--r-- | sys/kern/kern_switch.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_synch.c | 44 | ||||
-rw-r--r-- | sys/sys/proc.h | 2 |
3 files changed, 30 insertions, 18 deletions
diff --git a/sys/kern/kern_switch.c b/sys/kern/kern_switch.c index 97dd771..f704121 100644 --- a/sys/kern/kern_switch.c +++ b/sys/kern/kern_switch.c @@ -156,8 +156,10 @@ retry: } 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; diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 4fd3393..fb33e51 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -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)", diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 2fec2de..e809646 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -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 |