diff options
author | Julian Elischer <julian@FreeBSD.org> | 2004-09-16 07:12:59 +0000 |
---|---|---|
committer | Julian Elischer <julian@FreeBSD.org> | 2004-09-16 07:12:59 +0000 |
commit | 14f0e2e9bf2529b504c3094971c553cadf813e83 (patch) | |
tree | d07e704218909383fd325c02883dbc86dfaeb565 /sys/kern/kern_switch.c | |
parent | f6ddde7cfab6f792eae237acefedeecc738c631a (diff) | |
download | src-14f0e2e9bf2529b504c3094971c553cadf813e83.tar.gz src-14f0e2e9bf2529b504c3094971c553cadf813e83.zip |
clean up thread runq accounting a bit.
MFC after: 3 days
Notes
Notes:
svn path=/head/; revision=135295
Diffstat (limited to 'sys/kern/kern_switch.c')
-rw-r--r-- | sys/kern/kern_switch.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/sys/kern/kern_switch.c b/sys/kern/kern_switch.c index 7d3a44f81e8c..ee04bf36ab96 100644 --- a/sys/kern/kern_switch.c +++ b/sys/kern/kern_switch.c @@ -192,7 +192,7 @@ retry: * sched_thread_exit() (local) * sched_switch() (local) * sched_thread_exit() (local) - * remrunqueue() (local) + * remrunqueue() (local) (not at the moment) */ static void slot_fill(struct ksegrp *kg) @@ -214,7 +214,6 @@ slot_fill(struct ksegrp *kg) */ if (td) { kg->kg_last_assigned = td; - kg->kg_avail_opennings--; sched_add(td, SRQ_BORING); CTR2(KTR_RUNQ, "slot_fill: td%p -> kg%p", td, kg); } else { @@ -250,7 +249,6 @@ remrunqueue(struct thread *td) if ((td->td_proc->p_flag & P_HADTHREADS) == 0) { /* remve from sys run queue and free up a slot */ sched_rem(td); - kg->kg_avail_opennings++; ke->ke_state = KES_THREAD; return; } @@ -265,7 +263,6 @@ remrunqueue(struct thread *td) * see if we need to move the KSE in the run queues. */ sched_rem(td); - kg->kg_avail_opennings++; ke->ke_state = KES_THREAD; td2 = kg->kg_last_assigned; KASSERT((td2 != NULL), ("last assigned has wrong value")); @@ -305,17 +302,16 @@ adjustrunqueue( struct thread *td, int newpri) /* It is a threaded process */ kg = td->td_ksegrp; - TD_SET_CAN_RUN(td); if (ke->ke_state == KES_ONRUNQ) { if (kg->kg_last_assigned == td) { kg->kg_last_assigned = TAILQ_PREV(td, threadqueue, td_runq); } sched_rem(td); - kg->kg_avail_opennings++; } TAILQ_REMOVE(&kg->kg_runq, td, td_runq); kg->kg_runnable--; + TD_SET_CAN_RUN(td); td->td_priority = newpri; setrunqueue(td, SRQ_BORING); } @@ -326,7 +322,6 @@ setrunqueue(struct thread *td, int flags) struct ksegrp *kg; struct thread *td2; struct thread *tda; - int count; CTR3(KTR_RUNQ, "setrunqueue: td:%p kg:%p pid:%d", td, td->td_ksegrp, td->td_proc->p_pid); @@ -352,14 +347,23 @@ setrunqueue(struct thread *td, int flags) } kg->kg_avail_opennings = 1; } - kg->kg_avail_opennings--; sched_add(td, flags); return; } + /* + * If the concurrency has reduced, and we would go in the + * assigned section, then keep removing entries from the + * system run queue, until we are not in that section + * or there is room for us to be put in that section. + * What we MUST avoid is the case where there are threads of less + * priority than the new one scheduled, but it can not + * be scheduled itself. That would lead to a non contiguous set + * of scheduled threads, and everything would break. + */ tda = kg->kg_last_assigned; - if ((kg->kg_avail_opennings <= 0) && - (tda && (tda->td_priority > td->td_priority))) { + while ((kg->kg_avail_opennings <= 0) && + (tda && (tda->td_priority > td->td_priority))) { /* * None free, but there is one we can commandeer. */ @@ -375,18 +379,12 @@ setrunqueue(struct thread *td, int flags) * Add the thread to the ksegrp's run queue at * the appropriate place. */ - count = 0; TAILQ_FOREACH(td2, &kg->kg_runq, td_runq) { if (td2->td_priority > td->td_priority) { kg->kg_runnable++; TAILQ_INSERT_BEFORE(td2, td, td_runq); break; } - /* XXX Debugging hack */ - if (++count > 10000) { - printf("setrunqueue(): corrupt kq_runq, td= %p\n", td); - panic("deadlock in setrunqueue"); - } } if (td2 == NULL) { /* We ran off the end of the TAILQ or it was empty. */ @@ -397,12 +395,15 @@ setrunqueue(struct thread *td, int flags) /* * If we have a slot to use, then put the thread on the system * run queue and if needed, readjust the last_assigned pointer. + * it may be that we need to schedule something anyhow + * even if the availabel slots are -ve so that + * all the items < last_assigned are scheduled. */ if (kg->kg_avail_opennings > 0) { if (tda == NULL) { /* * No pre-existing last assigned so whoever is first - * gets the KSE we brought in.. (maybe us) + * gets the slot.. (maybe us) */ td2 = TAILQ_FIRST(&kg->kg_runq); kg->kg_last_assigned = td2; @@ -411,13 +412,12 @@ setrunqueue(struct thread *td, int flags) } else { /* * We are past last_assigned, so - * gave the next slot to whatever is next, + * give the next slot to whatever is next, * which may or may not be us. */ td2 = TAILQ_NEXT(tda, td_runq); kg->kg_last_assigned = td2; } - kg->kg_avail_opennings--; sched_add(td2, flags); } else { CTR3(KTR_RUNQ, "setrunqueue: held: td%p kg%p pid%d", @@ -544,7 +544,7 @@ maybe_preempt(struct thread *td) kg = td->td_ksegrp; if (kg->kg_last_assigned == td) kg->kg_last_assigned = - TAILQ_PREV(td, threadqueue, td_runq); + TAILQ_PREV(td, threadqueue, td_runq); TAILQ_REMOVE(&kg->kg_runq, td, td_runq); } |