kern_synch.c revision 1.177.2.12 1 /* $NetBSD: kern_synch.c,v 1.177.2.12 2007/03/03 15:37:41 yamt Exp $ */
2
3 /*-
4 * Copyright (c) 1999, 2000, 2004, 2006, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, by Charles M. Hannum, Andrew Doran and
10 * Daniel Sieger.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 /*-
42 * Copyright (c) 1982, 1986, 1990, 1991, 1993
43 * The Regents of the University of California. All rights reserved.
44 * (c) UNIX System Laboratories, Inc.
45 * All or some portions of this file are derived from material licensed
46 * to the University of California by American Telephone and Telegraph
47 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
48 * the permission of UNIX System Laboratories, Inc.
49 *
50 * Redistribution and use in source and binary forms, with or without
51 * modification, are permitted provided that the following conditions
52 * are met:
53 * 1. Redistributions of source code must retain the above copyright
54 * notice, this list of conditions and the following disclaimer.
55 * 2. Redistributions in binary form must reproduce the above copyright
56 * notice, this list of conditions and the following disclaimer in the
57 * documentation and/or other materials provided with the distribution.
58 * 3. Neither the name of the University nor the names of its contributors
59 * may be used to endorse or promote products derived from this software
60 * without specific prior written permission.
61 *
62 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
63 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
64 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
65 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
66 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72 * SUCH DAMAGE.
73 *
74 * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95
75 */
76
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.177.2.12 2007/03/03 15:37:41 yamt Exp $");
79
80 #include "opt_kstack.h"
81 #include "opt_lockdebug.h"
82 #include "opt_multiprocessor.h"
83 #include "opt_perfctrs.h"
84
85 #define __MUTEX_PRIVATE
86
87 #include <sys/param.h>
88 #include <sys/systm.h>
89 #include <sys/proc.h>
90 #include <sys/kernel.h>
91 #if defined(PERFCTRS)
92 #include <sys/pmc.h>
93 #endif
94 #include <sys/cpu.h>
95 #include <sys/resourcevar.h>
96 #include <sys/sched.h>
97 #include <sys/syscall_stats.h>
98 #include <sys/sleepq.h>
99 #include <sys/lockdebug.h>
100
101 #include <uvm/uvm_extern.h>
102
103 int lbolt; /* once a second sleep address */
104
105 /*
106 * The global scheduler state.
107 */
108 kmutex_t sched_mutex; /* global sched state mutex */
109
110 static void sched_unsleep(struct lwp *);
111 static void sched_changepri(struct lwp *, pri_t);
112 static void sched_lendpri(struct lwp *, pri_t);
113
114 syncobj_t sleep_syncobj = {
115 SOBJ_SLEEPQ_SORTED,
116 sleepq_unsleep,
117 sleepq_changepri,
118 sleepq_lendpri,
119 syncobj_noowner,
120 };
121
122 syncobj_t sched_syncobj = {
123 SOBJ_SLEEPQ_SORTED,
124 sched_unsleep,
125 sched_changepri,
126 sched_lendpri,
127 syncobj_noowner,
128 };
129
130 /*
131 * During autoconfiguration or after a panic, a sleep will simply lower the
132 * priority briefly to allow interrupts, then return. The priority to be
133 * used (safepri) is machine-dependent, thus this value is initialized and
134 * maintained in the machine-dependent layers. This priority will typically
135 * be 0, or the lowest priority that is safe for use on the interrupt stack;
136 * it can be made higher to block network software interrupts after panics.
137 */
138 int safepri;
139
140 /*
141 * OBSOLETE INTERFACE
142 *
143 * General sleep call. Suspends the current process until a wakeup is
144 * performed on the specified identifier. The process will then be made
145 * runnable with the specified priority. Sleeps at most timo/hz seconds (0
146 * means no timeout). If pri includes PCATCH flag, signals are checked
147 * before and after sleeping, else signals are not checked. Returns 0 if
148 * awakened, EWOULDBLOCK if the timeout expires. If PCATCH is set and a
149 * signal needs to be delivered, ERESTART is returned if the current system
150 * call should be restarted if possible, and EINTR is returned if the system
151 * call should be interrupted by the signal (return EINTR).
152 *
153 * The interlock is held until we are on a sleep queue. The interlock will
154 * be locked before returning back to the caller unless the PNORELOCK flag
155 * is specified, in which case the interlock will always be unlocked upon
156 * return.
157 */
158 int
159 ltsleep(wchan_t ident, pri_t priority, const char *wmesg, int timo,
160 volatile struct simplelock *interlock)
161 {
162 struct lwp *l = curlwp;
163 sleepq_t *sq;
164 int error, catch;
165
166 if (sleepq_dontsleep(l)) {
167 (void)sleepq_abort(NULL, 0);
168 if ((priority & PNORELOCK) != 0)
169 simple_unlock(interlock);
170 return 0;
171 }
172
173 sq = sleeptab_lookup(&sleeptab, ident);
174 sleepq_enter(sq, l);
175
176 if (interlock != NULL) {
177 LOCK_ASSERT(simple_lock_held(interlock));
178 simple_unlock(interlock);
179 }
180
181 catch = priority & PCATCH;
182 sleepq_block(sq, priority & PRIMASK, ident, wmesg, timo, catch,
183 &sleep_syncobj);
184 error = sleepq_unblock(timo, catch);
185
186 if (interlock != NULL && (priority & PNORELOCK) == 0)
187 simple_lock(interlock);
188
189 return error;
190 }
191
192 /*
193 * General sleep call for situations where a wake-up is not expected.
194 */
195 int
196 kpause(const char *wmesg, bool intr, int timo, kmutex_t *mtx)
197 {
198 struct lwp *l = curlwp;
199 sleepq_t *sq;
200 int error;
201
202 if (sleepq_dontsleep(l))
203 return sleepq_abort(NULL, 0);
204
205 if (mtx != NULL)
206 mutex_exit(mtx);
207 sq = sleeptab_lookup(&sleeptab, l);
208 sleepq_enter(sq, l);
209 sleepq_block(sq, sched_kpri(l), l, wmesg, timo, intr, &sleep_syncobj);
210 error = sleepq_unblock(timo, intr);
211 if (mtx != NULL)
212 mutex_enter(mtx);
213
214 return error;
215 }
216
217 /*
218 * OBSOLETE INTERFACE
219 *
220 * Make all processes sleeping on the specified identifier runnable.
221 */
222 void
223 wakeup(wchan_t ident)
224 {
225 sleepq_t *sq;
226
227 if (cold)
228 return;
229
230 sq = sleeptab_lookup(&sleeptab, ident);
231 sleepq_wake(sq, ident, (u_int)-1);
232 }
233
234 /*
235 * OBSOLETE INTERFACE
236 *
237 * Make the highest priority process first in line on the specified
238 * identifier runnable.
239 */
240 void
241 wakeup_one(wchan_t ident)
242 {
243 sleepq_t *sq;
244
245 if (cold)
246 return;
247
248 sq = sleeptab_lookup(&sleeptab, ident);
249 sleepq_wake(sq, ident, 1);
250 }
251
252
253 /*
254 * General yield call. Puts the current process back on its run queue and
255 * performs a voluntary context switch. Should only be called when the
256 * current process explicitly requests it (eg sched_yield(2) in compat code).
257 */
258 void
259 yield(void)
260 {
261 struct lwp *l = curlwp;
262
263 KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
264 lwp_lock(l);
265 if (l->l_stat == LSONPROC) {
266 KASSERT(lwp_locked(l, &sched_mutex));
267 l->l_priority = l->l_usrpri;
268 }
269 l->l_nvcsw++;
270 mi_switch(l, NULL);
271 KERNEL_LOCK(l->l_biglocks, l);
272 }
273
274 /*
275 * General preemption call. Puts the current process back on its run queue
276 * and performs an involuntary context switch.
277 */
278 void
279 preempt(void)
280 {
281 struct lwp *l = curlwp;
282
283 KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
284 lwp_lock(l);
285 if (l->l_stat == LSONPROC) {
286 KASSERT(lwp_locked(l, &sched_mutex));
287 l->l_priority = l->l_usrpri;
288 }
289 l->l_nivcsw++;
290 (void)mi_switch(l, NULL);
291 KERNEL_LOCK(l->l_biglocks, l);
292 }
293
294 /*
295 * sched_switch_unlock: update 'curlwp' and release old lwp.
296 */
297
298 void
299 sched_switch_unlock(struct lwp *old, struct lwp *new)
300 {
301
302 KASSERT(old == NULL || old == curlwp);
303 KASSERT(new != NULL);
304
305 if (old != NULL) {
306 LOCKDEBUG_BARRIER(old->l_mutex, 1);
307 } else {
308 LOCKDEBUG_BARRIER(NULL, 1);
309 }
310
311 curlwp = new;
312 if (old != NULL) {
313 lwp_unlock(old);
314 }
315 spl0();
316 }
317
318 /*
319 * Compute the amount of time during which the current lwp was running.
320 *
321 * - update l_rtime unless it's an idle lwp.
322 * - update spc_runtime for the next lwp.
323 */
324
325 static inline void
326 updatertime(struct lwp *l, struct schedstate_percpu *spc)
327 {
328 struct timeval tv;
329 long s, u;
330
331 if ((l->l_flag & LW_IDLE) != 0) {
332 microtime(&spc->spc_runtime);
333 return;
334 }
335
336 microtime(&tv);
337 u = l->l_rtime.tv_usec + (tv.tv_usec - spc->spc_runtime.tv_usec);
338 s = l->l_rtime.tv_sec + (tv.tv_sec - spc->spc_runtime.tv_sec);
339 if (u < 0) {
340 u += 1000000;
341 s--;
342 } else if (u >= 1000000) {
343 u -= 1000000;
344 s++;
345 }
346 l->l_rtime.tv_usec = u;
347 l->l_rtime.tv_sec = s;
348
349 spc->spc_runtime = tv;
350 }
351
352 /*
353 * The machine independent parts of context switch. Switch to "new"
354 * if non-NULL, otherwise let cpu_switch choose the next lwp.
355 *
356 * Returns 1 if another process was actually run.
357 */
358 int
359 mi_switch(struct lwp *l, struct lwp *newl)
360 {
361 struct schedstate_percpu *spc;
362 int retval, oldspl;
363
364 LOCK_ASSERT(lwp_locked(l, NULL));
365
366 #ifdef LOCKDEBUG
367 spinlock_switchcheck();
368 simple_lock_switchcheck();
369 #endif
370 #ifdef KSTACK_CHECK_MAGIC
371 kstack_check_magic(l);
372 #endif
373
374 /*
375 * It's safe to read the per CPU schedstate unlocked here, as all we
376 * are after is the run time and that's guarenteed to have been last
377 * updated by this CPU.
378 */
379 KDASSERT(l->l_cpu == curcpu());
380 spc = &l->l_cpu->ci_schedstate;
381
382 /* Count time spent in current system call */
383 SYSCALL_TIME_SLEEP(l);
384
385 /*
386 * XXXSMP If we are using h/w performance counters, save context.
387 */
388 #if PERFCTRS
389 if (PMC_ENABLED(l->l_proc)) {
390 pmc_save_context(l->l_proc);
391 }
392 #endif
393
394 /*
395 * If on the CPU and we have gotten this far, then we must yield.
396 */
397 KASSERT(l->l_stat != LSRUN);
398 if (l->l_stat == LSONPROC) {
399 KASSERT(lwp_locked(l, &sched_mutex));
400 l->l_stat = LSRUN;
401 if ((l->l_flag & LW_IDLE) == 0) {
402 sched_enqueue(l);
403 }
404 }
405 uvmexp.swtch++;
406
407 /*
408 * Process is about to yield the CPU; clear the appropriate
409 * scheduling flags.
410 */
411 spc->spc_flags &= ~SPCF_SWITCHCLEAR;
412
413 LOCKDEBUG_BARRIER(l->l_mutex, 1);
414
415 /*
416 * Switch to the new LWP if necessary.
417 * When we run again, we'll return back here.
418 */
419 oldspl = MUTEX_SPIN_OLDSPL(l->l_cpu);
420
421 /*
422 * Acquire the sched_mutex if necessary.
423 */
424 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
425 if (l->l_mutex != &sched_mutex) {
426 mutex_enter(&sched_mutex);
427 }
428 #endif
429
430 if (newl == NULL) {
431 newl = sched_nextlwp();
432 }
433 if (newl != NULL) {
434 KASSERT(lwp_locked(newl, &sched_mutex));
435 sched_dequeue(newl);
436 } else {
437 newl = l->l_cpu->ci_data.cpu_idlelwp;
438 KASSERT(newl != NULL);
439 }
440 KASSERT(lwp_locked(newl, &sched_mutex));
441 newl->l_stat = LSONPROC;
442 newl->l_cpu = l->l_cpu;
443
444 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
445 if (l->l_mutex != &sched_mutex) {
446 mutex_exit(&sched_mutex);
447 }
448 #endif
449
450 updatertime(l, spc);
451 if (l != newl) {
452 struct lwp *prevlwp;
453
454 uvmexp.swtch++;
455 pmap_deactivate(l);
456 prevlwp = cpu_switchto(l, newl);
457 sched_switch_unlock(prevlwp, l);
458 pmap_activate(l);
459 retval = 1;
460 } else {
461 sched_switch_unlock(l, l);
462 retval = 0;
463 }
464
465 KASSERT(l == curlwp);
466 KASSERT(l->l_stat == LSONPROC);
467
468 /*
469 * XXXSMP If we are using h/w performance counters, restore context.
470 */
471 #if PERFCTRS
472 if (PMC_ENABLED(l->l_proc)) {
473 pmc_restore_context(l->l_proc);
474 }
475 #endif
476
477 /*
478 * We're running again; record our new start time. We might
479 * be running on a new CPU now, so don't use the cached
480 * schedstate_percpu pointer.
481 */
482 SYSCALL_TIME_WAKEUP(l);
483 KDASSERT(l->l_cpu == curcpu());
484
485 (void)splsched();
486 splx(oldspl);
487 return retval;
488 }
489
490 /*
491 * Change process state to be runnable, placing it on the run queue if it is
492 * in memory, and awakening the swapper if it isn't in memory.
493 *
494 * Call with the process and LWP locked. Will return with the LWP unlocked.
495 */
496 void
497 setrunnable(struct lwp *l)
498 {
499 struct proc *p = l->l_proc;
500 sigset_t *ss;
501
502 KASSERT((l->l_flag & LW_IDLE) == 0);
503 KASSERT(mutex_owned(&p->p_smutex));
504 KASSERT(lwp_locked(l, NULL));
505
506 switch (l->l_stat) {
507 case LSSTOP:
508 /*
509 * If we're being traced (possibly because someone attached us
510 * while we were stopped), check for a signal from the debugger.
511 */
512 if ((p->p_slflag & PSL_TRACED) != 0 && p->p_xstat != 0) {
513 if ((sigprop[p->p_xstat] & SA_TOLWP) != 0)
514 ss = &l->l_sigpend.sp_set;
515 else
516 ss = &p->p_sigpend.sp_set;
517 sigaddset(ss, p->p_xstat);
518 signotify(l);
519 }
520 p->p_nrlwps++;
521 break;
522 case LSSUSPENDED:
523 l->l_flag &= ~LW_WSUSPEND;
524 p->p_nrlwps++;
525 break;
526 case LSSLEEP:
527 KASSERT(l->l_wchan != NULL);
528 break;
529 default:
530 panic("setrunnable: lwp %p state was %d", l, l->l_stat);
531 }
532
533 /*
534 * If the LWP was sleeping interruptably, then it's OK to start it
535 * again. If not, mark it as still sleeping.
536 */
537 if (l->l_wchan != NULL) {
538 l->l_stat = LSSLEEP;
539 /* lwp_unsleep() will release the lock. */
540 lwp_unsleep(l);
541 return;
542 }
543
544 LOCK_ASSERT(lwp_locked(l, &sched_mutex));
545
546 /*
547 * If the LWP is still on the CPU, mark it as LSONPROC. It may be
548 * about to call mi_switch(), in which case it will yield.
549 *
550 * XXXSMP Will need to change for preemption.
551 */
552 #ifdef MULTIPROCESSOR
553 if (l->l_cpu->ci_curlwp == l) {
554 #else
555 if (l == curlwp) {
556 #endif
557 l->l_stat = LSONPROC;
558 l->l_slptime = 0;
559 lwp_unlock(l);
560 return;
561 }
562
563 /*
564 * Set the LWP runnable. If it's swapped out, we need to wake the swapper
565 * to bring it back in. Otherwise, enter it into a run queue.
566 */
567 sched_setrunnable(l);
568 l->l_stat = LSRUN;
569 l->l_slptime = 0;
570
571 if (l->l_flag & LW_INMEM) {
572 sched_enqueue(l);
573 resched_cpu(l);
574 lwp_unlock(l);
575 } else {
576 lwp_unlock(l);
577 uvm_kick_scheduler();
578 }
579 }
580
581 /*
582 * suspendsched:
583 *
584 * Convert all non-L_SYSTEM LSSLEEP or LSRUN LWPs to LSSUSPENDED.
585 */
586 void
587 suspendsched(void)
588 {
589 #ifdef MULTIPROCESSOR
590 CPU_INFO_ITERATOR cii;
591 struct cpu_info *ci;
592 #endif
593 struct lwp *l;
594 struct proc *p;
595
596 /*
597 * We do this by process in order not to violate the locking rules.
598 */
599 mutex_enter(&proclist_mutex);
600 PROCLIST_FOREACH(p, &allproc) {
601 mutex_enter(&p->p_smutex);
602
603 if ((p->p_flag & PK_SYSTEM) != 0) {
604 mutex_exit(&p->p_smutex);
605 continue;
606 }
607
608 p->p_stat = SSTOP;
609
610 LIST_FOREACH(l, &p->p_lwps, l_sibling) {
611 if (l == curlwp)
612 continue;
613
614 lwp_lock(l);
615
616 /*
617 * Set L_WREBOOT so that the LWP will suspend itself
618 * when it tries to return to user mode. We want to
619 * try and get to get as many LWPs as possible to
620 * the user / kernel boundary, so that they will
621 * release any locks that they hold.
622 */
623 l->l_flag |= (LW_WREBOOT | LW_WSUSPEND);
624
625 if (l->l_stat == LSSLEEP &&
626 (l->l_flag & LW_SINTR) != 0) {
627 /* setrunnable() will release the lock. */
628 setrunnable(l);
629 continue;
630 }
631
632 lwp_unlock(l);
633 }
634
635 mutex_exit(&p->p_smutex);
636 }
637 mutex_exit(&proclist_mutex);
638
639 /*
640 * Kick all CPUs to make them preempt any LWPs running in user mode.
641 * They'll trap into the kernel and suspend themselves in userret().
642 */
643 sched_lock(0);
644 #ifdef MULTIPROCESSOR
645 for (CPU_INFO_FOREACH(cii, ci))
646 cpu_need_resched(ci, 0);
647 #else
648 cpu_need_resched(curcpu(), 0);
649 #endif
650 sched_unlock(0);
651 }
652
653 /*
654 * sched_kpri:
655 *
656 * Scale a priority level to a kernel priority level, usually
657 * for an LWP that is about to sleep.
658 */
659 pri_t
660 sched_kpri(struct lwp *l)
661 {
662 /*
663 * Scale user priorities (127 -> 50) up to kernel priorities
664 * in the range (49 -> 8). Reserve the top 8 kernel priorities
665 * for high priority kthreads. Kernel priorities passed in
666 * are left "as is". XXX This is somewhat arbitrary.
667 */
668 static const uint8_t kpri_tab[] = {
669 0, 1, 2, 3, 4, 5, 6, 7,
670 8, 9, 10, 11, 12, 13, 14, 15,
671 16, 17, 18, 19, 20, 21, 22, 23,
672 24, 25, 26, 27, 28, 29, 30, 31,
673 32, 33, 34, 35, 36, 37, 38, 39,
674 40, 41, 42, 43, 44, 45, 46, 47,
675 48, 49, 8, 8, 9, 9, 10, 10,
676 11, 11, 12, 12, 13, 14, 14, 15,
677 15, 16, 16, 17, 17, 18, 18, 19,
678 20, 20, 21, 21, 22, 22, 23, 23,
679 24, 24, 25, 26, 26, 27, 27, 28,
680 28, 29, 29, 30, 30, 31, 32, 32,
681 33, 33, 34, 34, 35, 35, 36, 36,
682 37, 38, 38, 39, 39, 40, 40, 41,
683 41, 42, 42, 43, 44, 44, 45, 45,
684 46, 46, 47, 47, 48, 48, 49, 49,
685 };
686
687 return (pri_t)kpri_tab[l->l_usrpri];
688 }
689
690 /*
691 * sched_unsleep:
692 *
693 * The is called when the LWP has not been awoken normally but instead
694 * interrupted: for example, if the sleep timed out. Because of this,
695 * it's not a valid action for running or idle LWPs.
696 */
697 static void
698 sched_unsleep(struct lwp *l)
699 {
700
701 lwp_unlock(l);
702 panic("sched_unsleep");
703 }
704
705 inline void
706 resched_cpu(struct lwp *l)
707 {
708 struct cpu_info *ci;
709 const pri_t pri = lwp_eprio(l);
710
711 /*
712 * XXXSMP
713 * Since l->l_cpu persists across a context switch,
714 * this gives us *very weak* processor affinity, in
715 * that we notify the CPU on which the process last
716 * ran that it should try to switch.
717 *
718 * This does not guarantee that the process will run on
719 * that processor next, because another processor might
720 * grab it the next time it performs a context switch.
721 *
722 * This also does not handle the case where its last
723 * CPU is running a higher-priority process, but every
724 * other CPU is running a lower-priority process. There
725 * are ways to handle this situation, but they're not
726 * currently very pretty, and we also need to weigh the
727 * cost of moving a process from one CPU to another.
728 *
729 * XXXSMP
730 * There is also the issue of locking the other CPU's
731 * sched state, which we currently do not do.
732 */
733 ci = (l->l_cpu != NULL) ? l->l_cpu : curcpu();
734 if (pri < ci->ci_schedstate.spc_curpriority)
735 cpu_need_resched(ci, 0);
736 }
737
738 static void
739 sched_changepri(struct lwp *l, pri_t pri)
740 {
741
742 LOCK_ASSERT(lwp_locked(l, &sched_mutex));
743
744 l->l_usrpri = pri;
745 if (l->l_priority < PUSER)
746 return;
747
748 if (l->l_stat != LSRUN || (l->l_flag & LW_INMEM) == 0) {
749 l->l_priority = pri;
750 return;
751 }
752
753 sched_dequeue(l);
754 l->l_priority = pri;
755 sched_enqueue(l);
756 resched_cpu(l);
757 }
758
759 static void
760 sched_lendpri(struct lwp *l, pri_t pri)
761 {
762
763 LOCK_ASSERT(lwp_locked(l, &sched_mutex));
764
765 if (l->l_stat != LSRUN || (l->l_flag & LW_INMEM) == 0) {
766 l->l_inheritedprio = pri;
767 return;
768 }
769
770 sched_dequeue(l);
771 l->l_inheritedprio = pri;
772 sched_enqueue(l);
773 resched_cpu(l);
774 }
775
776 struct lwp *
777 syncobj_noowner(wchan_t wchan)
778 {
779
780 return NULL;
781 }
782