xref: /freebsd/sys/kern/kern_switch.c (revision c3b98db091b192a2e4333df74ea6da2a6ea90d26)
1 /*
2  * Copyright (c) 2001 Jake Burkholder <jake@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 /***
30 
31 Here is the logic..
32 
33 If there are N processors, then there are at most N KSEs (kernel
34 schedulable entities) working to process threads that belong to a
35 KSEGOUP (kg). If there are X of these KSEs actually running at the
36 moment in question, then there are at most M (N-X) of these KSEs on
37 the run queue, as running KSEs are not on the queue.
38 
39 Runnable threads are queued off the KSEGROUP in priority order.
40 If there are M or more threads runnable, the top M threads
41 (by priority) are 'preassigned' to the M KSEs not running. The KSEs take
42 their priority from those threads and are put on the run queue.
43 
44 The last thread that had a priority high enough to have a KSE associated
45 with it, AND IS ON THE RUN QUEUE is pointed to by
46 kg->kg_last_assigned. If no threads queued off the KSEGROUP have KSEs
47 assigned as all the available KSEs are activly running, or because there
48 are no threads queued, that pointer is NULL.
49 
50 When a KSE is removed from the run queue to become runnable, we know
51 it was associated with the highest priority thread in the queue (at the head
52 of the queue). If it is also the last assigned we know M was 1 and must
53 now be 0. Since the thread is no longer queued that pointer must be
54 removed from it. Since we know there were no more KSEs available,
55 (M was 1 and is now 0) and since we are not FREEING our KSE
56 but using it, we know there are STILL no more KSEs available, we can prove
57 that the next thread in the ksegrp list will not have a KSE to assign to
58 it, so we can show that the pointer must be made 'invalid' (NULL).
59 
60 The pointer exists so that when a new thread is made runnable, it can
61 have its priority compared with the last assigned thread to see if
62 it should 'steal' its KSE or not.. i.e. is it 'earlier'
63 on the list than that thread or later.. If it's earlier, then the KSE is
64 removed from the last assigned (which is now not assigned a KSE)
65 and reassigned to the new thread, which is placed earlier in the list.
66 The pointer is then backed up to the previous thread (which may or may not
67 be the new thread).
68 
69 When a thread sleeps or is removed, the KSE becomes available and if there
70 are queued threads that are not assigned KSEs, the highest priority one of
71 them is assigned the KSE, which is then placed back on the run queue at
72 the approipriate place, and the kg->kg_last_assigned pointer is adjusted down
73 to point to it.
74 
75 The following diagram shows 2 KSEs and 3 threads from a single process.
76 
77  RUNQ: --->KSE---KSE--...    (KSEs queued at priorities from threads)
78               \    \____
79                \        \
80     KSEGROUP---thread--thread--thread    (queued in priority order)
81         \                 /
82          \_______________/
83           (last_assigned)
84 
85 The result of this scheme is that the M available KSEs are always
86 queued at the priorities they have inherrited from the M highest priority
87 threads for that KSEGROUP. If this situation changes, the KSEs are
88 reassigned to keep this true.
89 
90 */
91 
92 #include <sys/param.h>
93 #include <sys/systm.h>
94 #include <sys/kernel.h>
95 #include <sys/ktr.h>
96 #include <sys/lock.h>
97 #include <sys/mutex.h>
98 #include <sys/proc.h>
99 #include <sys/queue.h>
100 #include <machine/critical.h>
101 
102 CTASSERT((RQB_BPW * RQB_LEN) == RQ_NQS);
103 
104 /*
105  * Global run queue.
106  */
107 static struct runq runq;
108 SYSINIT(runq, SI_SUB_RUN_QUEUE, SI_ORDER_FIRST, runq_init, &runq)
109 
110 static void runq_readjust(struct runq *rq, struct kse *ke);
111 /************************************************************************
112  * Functions that manipulate runnability from a thread perspective.	*
113  ************************************************************************/
114 
115 /*
116  * Select the KSE that will be run next.  From that find the thread, and x
117  * remove it from the KSEGRP's run queue.  If there is thread clustering,
118  * this will be what does it.
119  */
120 struct thread *
121 choosethread(void)
122 {
123 	struct kse *ke;
124 	struct thread *td;
125 	struct ksegrp *kg;
126 
127 	if ((ke = runq_choose(&runq))) {
128 		td = ke->ke_thread;
129 		KASSERT((td->td_kse == ke), ("kse/thread mismatch"));
130 		kg = ke->ke_ksegrp;
131 		if (td->td_flags & TDF_UNBOUND) {
132 			TAILQ_REMOVE(&kg->kg_runq, td, td_runq);
133 			if (kg->kg_last_assigned == td)
134 				if (TAILQ_PREV(td, threadqueue, td_runq)
135 				    != NULL)
136 					printf("Yo MAMA!\n");
137 				kg->kg_last_assigned = TAILQ_PREV(td,
138 				    threadqueue, td_runq);
139 			/*
140 			 *  If we have started running an upcall,
141 			 * Then TDF_UNBOUND WAS set because the thread was
142 			 * created without a KSE. Now that we have one,
143 			 * and it is our time to run, we make sure
144 			 * that BOUND semantics apply for the rest of
145 			 * the journey to userland, and into the UTS.
146 			 */
147 #ifdef	NOTYET
148 			if (td->td_flags & TDF_UPCALLING)
149 				tdf->td_flags &= ~TDF_UNBOUND;
150 #endif
151 		}
152 		kg->kg_runnable--;
153 		CTR2(KTR_RUNQ, "choosethread: td=%p pri=%d",
154 		    td, td->td_priority);
155 	} else {
156 		/* Simulate runq_choose() having returned the idle thread */
157 		td = PCPU_GET(idlethread);
158 		CTR1(KTR_RUNQ, "choosethread: td=%p (idle)", td);
159 	}
160 	td->td_state = TDS_RUNNING;
161 	return (td);
162 }
163 
164 /*
165  * Given a KSE (now surplus), either assign a new runable thread to it
166  * (and put it in the run queue) or put it in the ksegrp's idle KSE list.
167  * Assumes the kse is not linked to any threads any more. (has been cleaned).
168  */
169 void
170 kse_reassign(struct kse *ke)
171 {
172 	struct ksegrp *kg;
173 	struct thread *td;
174 
175 	kg = ke->ke_ksegrp;
176 
177 	/*
178 	 * Find the first unassigned thread
179 	 * If there is a 'last assigned' then see what's next.
180 	 * otherwise look at what is first.
181 	 */
182 	if ((td = kg->kg_last_assigned)) {
183 		td = TAILQ_NEXT(td, td_runq);
184 	} else {
185 		td = TAILQ_FIRST(&kg->kg_runq);
186 	}
187 
188 	/*
189 	 * If we found one assign it the kse, otherwise idle the kse.
190 	 */
191 	if (td) {
192 		kg->kg_last_assigned = td;
193 		td->td_kse = ke;
194 		ke->ke_thread = td;
195 		runq_add(&runq, ke);
196 		CTR2(KTR_RUNQ, "kse_reassign: ke%p -> td%p", ke, td);
197 	} else {
198 		ke->ke_state = KES_IDLE;
199 		ke->ke_thread = NULL;
200 		TAILQ_INSERT_HEAD(&kg->kg_iq, ke, ke_kgrlist);
201 		kg->kg_idle_kses++;
202 		CTR1(KTR_RUNQ, "kse_reassign: ke%p idled", ke);
203 	}
204 }
205 
206 int
207 kserunnable(void)
208 {
209 	return runq_check(&runq);
210 }
211 
212 /*
213  * Remove a thread from its KSEGRP's run queue.
214  * This in turn may remove it from a KSE if it was already assigned
215  * to one, possibly causing a new thread to be assigned to the KSE
216  * and the KSE getting a new priority (unless it's a BOUND thread/KSE pair).
217  */
218 void
219 remrunqueue(struct thread *td)
220 {
221 	struct thread *td2, *td3;
222 	struct ksegrp *kg;
223 	struct kse *ke;
224 
225 	mtx_assert(&sched_lock, MA_OWNED);
226 	KASSERT ((td->td_state == TDS_RUNQ),
227 		("remrunqueue: Bad state on run queue"));
228 	kg = td->td_ksegrp;
229 	ke = td->td_kse;
230 	/*
231 	 * If it's a bound thread/KSE pair, take the shortcut. All non-KSE
232 	 * threads are BOUND.
233 	 */
234 	CTR1(KTR_RUNQ, "remrunqueue: td%p", td);
235 	td->td_state = TDS_UNQUEUED;
236 	kg->kg_runnable--;
237 	if ((td->td_flags & TDF_UNBOUND) == 0)  {
238 		/* Bring its kse with it, leave the thread attached */
239 		runq_remove(&runq, ke);
240 		ke->ke_state = KES_THREAD;
241 		return;
242 	}
243 	if (ke) {
244 		/*
245 		 * This thread has been assigned to a KSE.
246 		 * We need to dissociate it and try assign the
247 		 * KSE to the next available thread. Then, we should
248 		 * see if we need to move the KSE in the run queues.
249 		 */
250 		td2 = kg->kg_last_assigned;
251 		KASSERT((td2 != NULL), ("last assigned has wrong value "));
252 		td->td_kse = NULL;
253 		if ((td3 = TAILQ_NEXT(td2, td_runq))) {
254 			KASSERT(td3 != td, ("td3 somehow matched td"));
255 			/*
256 			 * Give the next unassigned thread to the KSE
257 			 * so the number of runnable KSEs remains
258 			 * constant.
259 			 */
260 			td3->td_kse = ke;
261 			ke->ke_thread = td3;
262 			kg->kg_last_assigned = td3;
263 			runq_readjust(&runq, ke);
264 		} else {
265 			/*
266 			 * There is no unassigned thread.
267 			 * If we were the last assigned one,
268 			 * adjust the last assigned pointer back
269 			 * one, which may result in NULL.
270 			 */
271 			if (td == td2) {
272 				kg->kg_last_assigned =
273 				    TAILQ_PREV(td, threadqueue, td_runq);
274 			}
275 			runq_remove(&runq, ke);
276 			KASSERT((ke->ke_state != KES_IDLE),
277 			    ("kse already idle"));
278 			ke->ke_state = KES_IDLE;
279 			ke->ke_thread = NULL;
280 			TAILQ_INSERT_HEAD(&kg->kg_iq, ke, ke_kgrlist);
281 			kg->kg_idle_kses++;
282 		}
283 	}
284 	TAILQ_REMOVE(&kg->kg_runq, td, td_runq);
285 }
286 
287 void
288 setrunqueue(struct thread *td)
289 {
290 	struct kse *ke;
291 	struct ksegrp *kg;
292 	struct thread *td2;
293 	struct thread *tda;
294 
295 	CTR1(KTR_RUNQ, "setrunqueue: td%p", td);
296 	mtx_assert(&sched_lock, MA_OWNED);
297 	KASSERT((td->td_state != TDS_RUNQ), ("setrunqueue: bad thread state"));
298 	td->td_state = TDS_RUNQ;
299 	kg = td->td_ksegrp;
300 	kg->kg_runnable++;
301 	if ((td->td_flags & TDF_UNBOUND) == 0) {
302 		KASSERT((td->td_kse != NULL),
303 		    ("queueing BAD thread to run queue"));
304 		/*
305 		 * Common path optimisation: Only one of everything
306 		 * and the KSE is always already attached.
307 		 * Totally ignore the ksegrp run queue.
308 		 */
309 		runq_add(&runq, td->td_kse);
310 		return;
311 	}
312 	/*
313 	 * Ok, so we are threading with this thread.
314 	 * We don't have a KSE, see if we can get one..
315 	 */
316 	tda = kg->kg_last_assigned;
317 	if ((ke = td->td_kse) == NULL) {
318 		/*
319 		 * We will need a KSE, see if there is one..
320 		 * First look for a free one, before getting desperate.
321 		 * If we can't get one, our priority is not high enough..
322 		 * that's ok..
323 		 */
324 		if (kg->kg_idle_kses) {
325 			/*
326 			 * There is a free one so it's ours for the asking..
327 			 */
328 			ke = TAILQ_FIRST(&kg->kg_iq);
329 			TAILQ_REMOVE(&kg->kg_iq, ke, ke_kgrlist);
330 			ke->ke_state = KES_THREAD;
331 			kg->kg_idle_kses--;
332 		} else if (tda && (tda->td_priority > td->td_priority)) {
333 			/*
334 			 * None free, but there is one we can commandeer.
335 			 */
336 			ke = tda->td_kse;
337 			tda->td_kse = NULL;
338 			ke->ke_thread = NULL;
339 			tda = kg->kg_last_assigned =
340 		    	    TAILQ_PREV(tda, threadqueue, td_runq);
341 			runq_remove(&runq, ke);
342 		}
343 	} else {
344 		/*
345 		 * Temporarily disassociate so it looks like the other cases.
346 		 */
347 		ke->ke_thread = NULL;
348 		td->td_kse = NULL;
349 	}
350 
351 	/*
352 	 * Add the thread to the ksegrp's run queue at
353 	 * the appropriate place.
354 	 */
355 	TAILQ_FOREACH(td2, &kg->kg_runq, td_runq) {
356 		if (td2->td_priority > td->td_priority) {
357 			TAILQ_INSERT_BEFORE(td2, td, td_runq);
358 			break;
359 		}
360 	}
361 	if (td2 == NULL) {
362 		/* We ran off the end of the TAILQ or it was empty. */
363 		TAILQ_INSERT_TAIL(&kg->kg_runq, td, td_runq);
364 	}
365 
366 	/*
367 	 * If we have a ke to use, then put it on the run queue and
368 	 * If needed, readjust the last_assigned pointer.
369 	 */
370 	if (ke) {
371 		if (tda == NULL) {
372 			/*
373 			 * No pre-existing last assigned so whoever is first
374 			 * gets the KSE we brought in.. (maybe us)
375 			 */
376 			td2 = TAILQ_FIRST(&kg->kg_runq);
377 			KASSERT((td2->td_kse == NULL),
378 			    ("unexpected ke present"));
379 			td2->td_kse = ke;
380 			ke->ke_thread = td2;
381 			kg->kg_last_assigned = td2;
382 		} else if (tda->td_priority > td->td_priority) {
383 			/*
384 			 * It's ours, grab it, but last_assigned is past us
385 			 * so don't change it.
386 			 */
387 			td->td_kse = ke;
388 			ke->ke_thread = td;
389 		} else {
390 			/*
391 			 * We are past last_assigned, so
392 			 * put the new kse on whatever is next,
393 			 * which may or may not be us.
394 			 */
395 			td2 = TAILQ_NEXT(tda, td_runq);
396 			kg->kg_last_assigned = td2;
397 			td2->td_kse = ke;
398 			ke->ke_thread = td2;
399 		}
400 		runq_add(&runq, ke);
401 	}
402 }
403 
404 /************************************************************************
405  * Critical section marker functions					*
406  ************************************************************************/
407 /* Critical sections that prevent preemption. */
408 void
409 critical_enter(void)
410 {
411 	struct thread *td;
412 
413 	td = curthread;
414 	if (td->td_critnest == 0)
415 		cpu_critical_enter();
416 	td->td_critnest++;
417 }
418 
419 void
420 critical_exit(void)
421 {
422 	struct thread *td;
423 
424 	td = curthread;
425 	if (td->td_critnest == 1) {
426 		td->td_critnest = 0;
427 		cpu_critical_exit();
428 	} else {
429 		td->td_critnest--;
430 	}
431 }
432 
433 
434 /************************************************************************
435  * SYSTEM RUN QUEUE manipulations and tests				*
436  ************************************************************************/
437 /*
438  * Initialize a run structure.
439  */
440 void
441 runq_init(struct runq *rq)
442 {
443 	int i;
444 
445 	bzero(rq, sizeof *rq);
446 	for (i = 0; i < RQ_NQS; i++)
447 		TAILQ_INIT(&rq->rq_queues[i]);
448 }
449 
450 /*
451  * Clear the status bit of the queue corresponding to priority level pri,
452  * indicating that it is empty.
453  */
454 static __inline void
455 runq_clrbit(struct runq *rq, int pri)
456 {
457 	struct rqbits *rqb;
458 
459 	rqb = &rq->rq_status;
460 	CTR4(KTR_RUNQ, "runq_clrbit: bits=%#x %#x bit=%#x word=%d",
461 	    rqb->rqb_bits[RQB_WORD(pri)],
462 	    rqb->rqb_bits[RQB_WORD(pri)] & ~RQB_BIT(pri),
463 	    RQB_BIT(pri), RQB_WORD(pri));
464 	rqb->rqb_bits[RQB_WORD(pri)] &= ~RQB_BIT(pri);
465 }
466 
467 /*
468  * Find the index of the first non-empty run queue.  This is done by
469  * scanning the status bits, a set bit indicates a non-empty queue.
470  */
471 static __inline int
472 runq_findbit(struct runq *rq)
473 {
474 	struct rqbits *rqb;
475 	int pri;
476 	int i;
477 
478 	rqb = &rq->rq_status;
479 	for (i = 0; i < RQB_LEN; i++)
480 		if (rqb->rqb_bits[i]) {
481 			pri = RQB_FFS(rqb->rqb_bits[i]) + (i << RQB_L2BPW);
482 			CTR3(KTR_RUNQ, "runq_findbit: bits=%#x i=%d pri=%d",
483 			    rqb->rqb_bits[i], i, pri);
484 			return (pri);
485 		}
486 
487 	return (-1);
488 }
489 
490 /*
491  * Set the status bit of the queue corresponding to priority level pri,
492  * indicating that it is non-empty.
493  */
494 static __inline void
495 runq_setbit(struct runq *rq, int pri)
496 {
497 	struct rqbits *rqb;
498 
499 	rqb = &rq->rq_status;
500 	CTR4(KTR_RUNQ, "runq_setbit: bits=%#x %#x bit=%#x word=%d",
501 	    rqb->rqb_bits[RQB_WORD(pri)],
502 	    rqb->rqb_bits[RQB_WORD(pri)] | RQB_BIT(pri),
503 	    RQB_BIT(pri), RQB_WORD(pri));
504 	rqb->rqb_bits[RQB_WORD(pri)] |= RQB_BIT(pri);
505 }
506 
507 /*
508  * Add the KSE to the queue specified by its priority, and set the
509  * corresponding status bit.
510  */
511 void
512 runq_add(struct runq *rq, struct kse *ke)
513 {
514 	struct rqhead *rqh;
515 	int pri;
516 
517 	mtx_assert(&sched_lock, MA_OWNED);
518 	KASSERT((ke->ke_thread != NULL), ("runq_add: No thread on KSE"));
519 	KASSERT((ke->ke_thread->td_kse != NULL),
520 	    ("runq_add: No KSE on thread"));
521 	KASSERT(ke->ke_state != KES_ONRUNQ,
522 	    ("runq_add: kse %p (%s) already in run queue", ke,
523 	    ke->ke_proc->p_comm));
524 	pri = ke->ke_thread->td_priority / RQ_PPQ;
525 	ke->ke_rqindex = pri;
526 	runq_setbit(rq, pri);
527 	rqh = &rq->rq_queues[pri];
528 	CTR4(KTR_RUNQ, "runq_add: p=%p pri=%d %d rqh=%p",
529 	    ke->ke_proc, ke->ke_thread->td_priority, pri, rqh);
530 	TAILQ_INSERT_TAIL(rqh, ke, ke_procq);
531 	ke->ke_ksegrp->kg_runq_kses++;
532 	ke->ke_state = KES_ONRUNQ;
533 }
534 
535 /*
536  * Return true if there are runnable processes of any priority on the run
537  * queue, false otherwise.  Has no side effects, does not modify the run
538  * queue structure.
539  */
540 int
541 runq_check(struct runq *rq)
542 {
543 	struct rqbits *rqb;
544 	int i;
545 
546 	rqb = &rq->rq_status;
547 	for (i = 0; i < RQB_LEN; i++)
548 		if (rqb->rqb_bits[i]) {
549 			CTR2(KTR_RUNQ, "runq_check: bits=%#x i=%d",
550 			    rqb->rqb_bits[i], i);
551 			return (1);
552 		}
553 	CTR0(KTR_RUNQ, "runq_check: empty");
554 
555 	return (0);
556 }
557 
558 /*
559  * Find and remove the highest priority process from the run queue.
560  * If there are no runnable processes, the per-cpu idle process is
561  * returned.  Will not return NULL under any circumstances.
562  */
563 struct kse *
564 runq_choose(struct runq *rq)
565 {
566 	struct rqhead *rqh;
567 	struct kse *ke;
568 	int pri;
569 
570 	mtx_assert(&sched_lock, MA_OWNED);
571 	while ((pri = runq_findbit(rq)) != -1) {
572 		rqh = &rq->rq_queues[pri];
573 		ke = TAILQ_FIRST(rqh);
574 		KASSERT(ke != NULL, ("runq_choose: no proc on busy queue"));
575 		CTR3(KTR_RUNQ,
576 		    "runq_choose: pri=%d kse=%p rqh=%p", pri, ke, rqh);
577 		TAILQ_REMOVE(rqh, ke, ke_procq);
578 		ke->ke_ksegrp->kg_runq_kses--;
579 		if (TAILQ_EMPTY(rqh)) {
580 			CTR0(KTR_RUNQ, "runq_choose: empty");
581 			runq_clrbit(rq, pri);
582 		}
583 
584 		ke->ke_state = KES_THREAD;
585 		KASSERT((ke->ke_thread != NULL),
586 		    ("runq_choose: No thread on KSE"));
587 		KASSERT((ke->ke_thread->td_kse != NULL),
588 		    ("runq_choose: No KSE on thread"));
589 		return (ke);
590 	}
591 	CTR1(KTR_RUNQ, "runq_choose: idleproc pri=%d", pri);
592 
593 	return (NULL);
594 }
595 
596 /*
597  * Remove the KSE from the queue specified by its priority, and clear the
598  * corresponding status bit if the queue becomes empty.
599  * Caller must set ke->ke_state afterwards.
600  */
601 void
602 runq_remove(struct runq *rq, struct kse *ke)
603 {
604 	struct rqhead *rqh;
605 	int pri;
606 
607 	KASSERT((ke->ke_state == KES_ONRUNQ), ("KSE not on run queue"));
608 	mtx_assert(&sched_lock, MA_OWNED);
609 	pri = ke->ke_rqindex;
610 	rqh = &rq->rq_queues[pri];
611 	CTR4(KTR_RUNQ, "runq_remove: p=%p pri=%d %d rqh=%p",
612 	    ke, ke->ke_thread->td_priority, pri, rqh);
613 	KASSERT(ke != NULL, ("runq_remove: no proc on busy queue"));
614 	TAILQ_REMOVE(rqh, ke, ke_procq);
615 	if (TAILQ_EMPTY(rqh)) {
616 		CTR0(KTR_RUNQ, "runq_remove: empty");
617 		runq_clrbit(rq, pri);
618 	}
619 	ke->ke_state = KES_THREAD;
620 	ke->ke_ksegrp->kg_runq_kses--;
621 }
622 
623 static void
624 runq_readjust(struct runq *rq, struct kse *ke)
625 {
626 
627 	if (ke->ke_rqindex != (ke->ke_thread->td_priority / RQ_PPQ)) {
628 		runq_remove(rq, ke);
629 		runq_add(rq, ke);
630 	}
631 }
632 
633 #if 0
634 void
635 thread_sanity_check(struct thread *td)
636 {
637 	struct proc *p;
638 	struct ksegrp *kg;
639 	struct kse *ke;
640 	struct thread *td2;
641 	unsigned int prevpri;
642 	int	saw_lastassigned;
643 	int unassigned;
644 	int assigned;
645 
646 	p = td->td_proc;
647 	kg = td->td_ksegrp;
648 	ke = td->td_kse;
649 
650 	if (kg != &p->p_ksegrp) {
651 		panic ("wrong ksegrp");
652 	}
653 
654 	if (ke) {
655 		if (ke != &p->p_kse) {
656 			panic("wrong kse");
657 		}
658 		if (ke->ke_thread != td) {
659 			panic("wrong thread");
660 		}
661 	}
662 
663 	if ((p->p_flag & P_KSES) == 0) {
664 		if (ke == NULL) {
665 			panic("non KSE thread lost kse");
666 		}
667 	} else {
668 		prevpri = 0;
669 		saw_lastassigned = 0;
670 		unassigned = 0;
671 		assigned = 0;
672 		TAILQ_FOREACH(td2, &kg->kg_runq, td_runq) {
673 			if (td2->td_priority < prevpri) {
674 				panic("thread runqueue unosorted");
675 			}
676 			prevpri = td2->td_priority;
677 			if (td2->td_kse) {
678 				assigned++;
679 				if (unassigned) {
680 					panic("unassigned before assigned");
681 				}
682  				if  (kg->kg_last_assigned == NULL) {
683 					panic("lastassigned corrupt");
684 				}
685 				if (saw_lastassigned) {
686 					panic("last assigned not last");
687 				}
688 				if (td2->td_kse->ke_thread != td2) {
689 					panic("mismatched kse/thread");
690 				}
691 			} else {
692 				unassigned++;
693 			}
694 			if (td2 == kg->kg_last_assigned) {
695 				saw_lastassigned = 1;
696 				if (td2->td_kse == NULL) {
697 					panic("last assigned not assigned");
698 				}
699 			}
700 		}
701 		if (kg->kg_last_assigned && (saw_lastassigned == 0)) {
702 			panic("where on earth does lastassigned point?");
703 		}
704 		FOREACH_THREAD_IN_GROUP(kg, td2) {
705 			if (((td2->td_flags & TDF_UNBOUND) == 0) &&
706 			    (td2->td_state == TDS_RUNQ)) {
707 				assigned++;
708 				if (td2->td_kse == NULL) {
709 					panic ("BOUND thread with no KSE");
710 				}
711 			}
712 		}
713 #if 0
714 		if ((unassigned + assigned) != kg->kg_runnable) {
715 			panic("wrong number in runnable");
716 		}
717 #endif
718 	}
719 }
720 #endif
721 
722