kern_synch.c (82711) | kern_synch.c (83366) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95 | 1/*- 2 * Copyright (c) 1982, 1986, 1990, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kern_synch.c 8.9 (Berkeley) 5/19/95 |
39 * $FreeBSD: head/sys/kern/kern_synch.c 82711 2001-09-01 03:54:09Z dillon $ | 39 * $FreeBSD: head/sys/kern/kern_synch.c 83366 2001-09-12 08:38:13Z julian $ |
40 */ 41 42#include "opt_ddb.h" 43#include "opt_ktrace.h" 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/condvar.h> --- 54 unchanged lines hidden (view full) --- 102SYSCTL_PROC(_kern, OID_AUTO, quantum, CTLTYPE_INT|CTLFLAG_RW, 103 0, sizeof sched_quantum, sysctl_kern_quantum, "I", ""); 104 105/* 106 * Arrange to reschedule if necessary, taking the priorities and 107 * schedulers into account. 108 */ 109void | 40 */ 41 42#include "opt_ddb.h" 43#include "opt_ktrace.h" 44 45#include <sys/param.h> 46#include <sys/systm.h> 47#include <sys/condvar.h> --- 54 unchanged lines hidden (view full) --- 102SYSCTL_PROC(_kern, OID_AUTO, quantum, CTLTYPE_INT|CTLFLAG_RW, 103 0, sizeof sched_quantum, sysctl_kern_quantum, "I", ""); 104 105/* 106 * Arrange to reschedule if necessary, taking the priorities and 107 * schedulers into account. 108 */ 109void |
110maybe_resched(p) 111 struct proc *p; | 110maybe_resched(kg) 111 struct ksegrp *kg; |
112{ 113 114 mtx_assert(&sched_lock, MA_OWNED); | 112{ 113 114 mtx_assert(&sched_lock, MA_OWNED); |
115 if (p->p_pri.pri_level < curproc->p_pri.pri_level) 116 curproc->p_sflag |= PS_NEEDRESCHED; | 115 if (kg->kg_pri.pri_level < curthread->td_ksegrp->kg_pri.pri_level) 116 curthread->td_kse->ke_flags |= KEF_NEEDRESCHED; |
117} 118 119int 120roundrobin_interval(void) 121{ 122 return (sched_quantum); 123} 124 --- 115 unchanged lines hidden (view full) --- 240 */ 241/* ARGSUSED */ 242static void 243schedcpu(arg) 244 void *arg; 245{ 246 register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); 247 register struct proc *p; | 117} 118 119int 120roundrobin_interval(void) 121{ 122 return (sched_quantum); 123} 124 --- 115 unchanged lines hidden (view full) --- 240 */ 241/* ARGSUSED */ 242static void 243schedcpu(arg) 244 void *arg; 245{ 246 register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); 247 register struct proc *p; |
248 register struct kse *ke; 249 register struct ksegrp *kg; |
|
248 register int realstathz; | 250 register int realstathz; |
251 int awake; |
|
249 250 realstathz = stathz ? stathz : hz; 251 sx_slock(&allproc_lock); | 252 253 realstathz = stathz ? stathz : hz; 254 sx_slock(&allproc_lock); |
252 LIST_FOREACH(p, &allproc, p_list) { 253 /* 254 * Increment time in/out of memory and sleep time 255 * (if sleeping). We ignore overflow; with 16-bit int's 256 * (remember them?) overflow takes 45 days. 257 */ | 255 FOREACH_PROC_IN_SYSTEM(p) { |
258 mtx_lock_spin(&sched_lock); 259 p->p_swtime++; | 256 mtx_lock_spin(&sched_lock); 257 p->p_swtime++; |
260 if (p->p_stat == SSLEEP || p->p_stat == SSTOP) 261 p->p_slptime++; 262 p->p_pctcpu = (p->p_pctcpu * ccpu) >> FSHIFT; 263 /* 264 * If the process has slept the entire second, 265 * stop recalculating its priority until it wakes up. 266 */ 267 if (p->p_slptime > 1) { 268 mtx_unlock_spin(&sched_lock); 269 continue; 270 } | 258 FOREACH_KSEGRP_IN_PROC(p, kg) { 259 awake = 0; 260 FOREACH_KSE_IN_GROUP(kg, ke) { 261 /* 262 * Increment time in/out of memory and sleep 263 * time (if sleeping). We ignore overflow; 264 * with 16-bit int's (remember them?) 265 * overflow takes 45 days. 266 */ 267 /* XXXKSE */ 268 /* if ((ke->ke_flags & KEF_ONRUNQ) == 0) */ 269 if (p->p_stat == SSLEEP || p->p_stat == SSTOP) { 270 ke->ke_slptime++; 271 } else { 272 ke->ke_slptime = 0; 273 awake = 1; 274 } |
271 | 275 |
272 /* 273 * p_pctcpu is only for ps. 274 */ | 276 /* 277 * pctcpu is only for ps? 278 * Do it per kse.. and add them up at the end? 279 * XXXKSE 280 */ 281 ke->ke_pctcpu = (ke->ke_pctcpu * ccpu) >> FSHIFT; 282 /* 283 * If the kse has been idle the entire second, 284 * stop recalculating its priority until 285 * it wakes up. 286 */ 287 if (ke->ke_slptime > 1) { 288 continue; 289 } 290 |
275#if (FSHIFT >= CCPU_SHIFT) | 291#if (FSHIFT >= CCPU_SHIFT) |
276 p->p_pctcpu += (realstathz == 100)? 277 ((fixpt_t) p->p_cpticks) << (FSHIFT - CCPU_SHIFT): 278 100 * (((fixpt_t) p->p_cpticks) 279 << (FSHIFT - CCPU_SHIFT)) / realstathz; | 292 ke->ke_pctcpu += (realstathz == 100) ? 293 ((fixpt_t) ke->ke_cpticks) << 294 (FSHIFT - CCPU_SHIFT) : 295 100 * (((fixpt_t) ke->ke_cpticks) << 296 (FSHIFT - CCPU_SHIFT)) / realstathz; |
280#else | 297#else |
281 p->p_pctcpu += ((FSCALE - ccpu) * 282 (p->p_cpticks * FSCALE / realstathz)) >> FSHIFT; | 298 ke->ke_pctcpu += ((FSCALE - ccpu) * 299 (ke->ke_cpticks * FSCALE / realstathz)) >> 300 FSHIFT; |
283#endif | 301#endif |
284 p->p_cpticks = 0; 285 p->p_estcpu = decay_cpu(loadfac, p->p_estcpu); 286 resetpriority(p); 287 if (p->p_pri.pri_level >= PUSER) { 288 if (p->p_oncpu == NOCPU && /* idle */ 289 p->p_stat == SRUN && 290 (p->p_sflag & PS_INMEM) && 291 (p->p_pri.pri_level / RQ_PPQ) != 292 (p->p_pri.pri_user / RQ_PPQ)) { 293 remrunqueue(p); 294 p->p_pri.pri_level = p->p_pri.pri_user; 295 setrunqueue(p); 296 } else 297 p->p_pri.pri_level = p->p_pri.pri_user; 298 } | 302 ke->ke_cpticks = 0; 303 } /* end of kse loop */ 304 if (awake == 0) { 305 kg->kg_slptime++; 306 } else { 307 kg->kg_slptime = 0; 308 } 309 kg->kg_estcpu = decay_cpu(loadfac, kg->kg_estcpu); 310 resetpriority(kg); 311 if (kg->kg_pri.pri_level >= PUSER && 312 (p->p_sflag & PS_INMEM)) { 313 int changedqueue = 314 ((kg->kg_pri.pri_level / RQ_PPQ) != 315 (kg->kg_pri.pri_user / RQ_PPQ)); 316 317 kg->kg_pri.pri_level = kg->kg_pri.pri_user; 318 FOREACH_KSE_IN_GROUP(kg, ke) { 319 if ((ke->ke_oncpu == NOCPU) && /* idle */ 320 (p->p_stat == SRUN) && /* XXXKSE */ 321 changedqueue) { 322 remrunqueue(ke->ke_thread); 323 setrunqueue(ke->ke_thread); 324 } 325 } 326 } 327 } /* end of ksegrp loop */ |
299 mtx_unlock_spin(&sched_lock); | 328 mtx_unlock_spin(&sched_lock); |
300 } | 329 } /* end of process loop */ |
301 sx_sunlock(&allproc_lock); 302 vmmeter(); 303 wakeup((caddr_t)&lbolt); 304 callout_reset(&schedcpu_callout, hz, schedcpu, NULL); 305} 306 307/* 308 * Recalculate the priority of a process after it has slept for a while. 309 * For all load averages >= 1 and max p_estcpu of 255, sleeping for at 310 * least six times the loadfactor will decay p_estcpu to zero. 311 */ 312void | 330 sx_sunlock(&allproc_lock); 331 vmmeter(); 332 wakeup((caddr_t)&lbolt); 333 callout_reset(&schedcpu_callout, hz, schedcpu, NULL); 334} 335 336/* 337 * Recalculate the priority of a process after it has slept for a while. 338 * For all load averages >= 1 and max p_estcpu of 255, sleeping for at 339 * least six times the loadfactor will decay p_estcpu to zero. 340 */ 341void |
313updatepri(p) 314 register struct proc *p; | 342updatepri(td) 343 register struct thread *td; |
315{ | 344{ |
316 register unsigned int newcpu = p->p_estcpu; | 345 register struct ksegrp *kg; 346 register unsigned int newcpu; |
317 register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); 318 | 347 register fixpt_t loadfac = loadfactor(averunnable.ldavg[0]); 348 |
319 if (p->p_slptime > 5 * loadfac) 320 p->p_estcpu = 0; | 349 if (td == NULL) 350 return; 351 kg = td->td_ksegrp; 352 newcpu = kg->kg_estcpu; 353 if (kg->kg_slptime > 5 * loadfac) 354 kg->kg_estcpu = 0; |
321 else { | 355 else { |
322 p->p_slptime--; /* the first time was done in schedcpu */ 323 while (newcpu && --p->p_slptime) | 356 kg->kg_slptime--; /* the first time was done in schedcpu */ 357 while (newcpu && --kg->kg_slptime) |
324 newcpu = decay_cpu(loadfac, newcpu); | 358 newcpu = decay_cpu(loadfac, newcpu); |
325 p->p_estcpu = newcpu; | 359 kg->kg_estcpu = newcpu; |
326 } | 360 } |
327 resetpriority(p); | 361 resetpriority(td->td_ksegrp); |
328} 329 330/* 331 * We're only looking at 7 bits of the address; everything is 332 * aligned to 4, lots of things are aligned to greater powers 333 * of 2. Shift right by 8, i.e. drop the bottom 256 worth. 334 */ 335#define TABLESIZE 128 | 362} 363 364/* 365 * We're only looking at 7 bits of the address; everything is 366 * aligned to 4, lots of things are aligned to greater powers 367 * of 2. Shift right by 8, i.e. drop the bottom 256 worth. 368 */ 369#define TABLESIZE 128 |
336static TAILQ_HEAD(slpquehead, proc) slpque[TABLESIZE]; | 370static TAILQ_HEAD(slpquehead, thread) slpque[TABLESIZE]; |
337#define LOOKUP(x) (((intptr_t)(x) >> 8) & (TABLESIZE - 1)) 338 339void 340sleepinit(void) 341{ 342 int i; 343 344 sched_quantum = hz/10; --- 20 unchanged lines hidden (view full) --- 365int 366msleep(ident, mtx, priority, wmesg, timo) 367 void *ident; 368 struct mtx *mtx; 369 int priority, timo; 370 const char *wmesg; 371{ 372 struct proc *p = curproc; | 371#define LOOKUP(x) (((intptr_t)(x) >> 8) & (TABLESIZE - 1)) 372 373void 374sleepinit(void) 375{ 376 int i; 377 378 sched_quantum = hz/10; --- 20 unchanged lines hidden (view full) --- 399int 400msleep(ident, mtx, priority, wmesg, timo) 401 void *ident; 402 struct mtx *mtx; 403 int priority, timo; 404 const char *wmesg; 405{ 406 struct proc *p = curproc; |
407 struct thread *td = curthread; |
|
373 int sig, catch = priority & PCATCH; 374 int rval = 0; 375 WITNESS_SAVE_DECL(mtx); 376 377#ifdef KTRACE 378 if (p && KTRPOINT(p, KTR_CSW)) 379 ktrcsw(p->p_tracep, 1, 0); 380#endif --- 20 unchanged lines hidden (view full) --- 401 mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED); 402 WITNESS_SAVE(&mtx->mtx_object, mtx); 403 mtx_unlock_flags(mtx, MTX_NOSWITCH); 404 if (priority & PDROP) 405 mtx = NULL; 406 } 407 408 KASSERT(p != NULL, ("msleep1")); | 408 int sig, catch = priority & PCATCH; 409 int rval = 0; 410 WITNESS_SAVE_DECL(mtx); 411 412#ifdef KTRACE 413 if (p && KTRPOINT(p, KTR_CSW)) 414 ktrcsw(p->p_tracep, 1, 0); 415#endif --- 20 unchanged lines hidden (view full) --- 436 mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED); 437 WITNESS_SAVE(&mtx->mtx_object, mtx); 438 mtx_unlock_flags(mtx, MTX_NOSWITCH); 439 if (priority & PDROP) 440 mtx = NULL; 441 } 442 443 KASSERT(p != NULL, ("msleep1")); |
409 KASSERT(ident != NULL && p->p_stat == SRUN, ("msleep")); | 444 KASSERT(ident != NULL && td->td_proc->p_stat == SRUN, ("msleep")); |
410 | 445 |
411 p->p_wchan = ident; 412 p->p_wmesg = wmesg; 413 p->p_slptime = 0; 414 p->p_pri.pri_level = priority & PRIMASK; 415 CTR5(KTR_PROC, "msleep: proc %p (pid %d, %s) on %s (%p)", p, p->p_pid, 416 p->p_comm, wmesg, ident); 417 TAILQ_INSERT_TAIL(&slpque[LOOKUP(ident)], p, p_slpq); | 446 td->td_wchan = ident; 447 td->td_wmesg = wmesg; 448 td->td_kse->ke_slptime = 0; /* XXXKSE */ 449 td->td_ksegrp->kg_slptime = 0; 450 td->td_ksegrp->kg_pri.pri_level = priority & PRIMASK; 451 CTR5(KTR_PROC, "msleep: thread %p (pid %d, %s) on %s (%p)", 452 td, p->p_pid, p->p_comm, wmesg, ident); 453 TAILQ_INSERT_TAIL(&slpque[LOOKUP(ident)], td, td_slpq); |
418 if (timo) | 454 if (timo) |
419 callout_reset(&p->p_slpcallout, timo, endtsleep, p); | 455 callout_reset(&td->td_slpcallout, timo, endtsleep, td); |
420 /* 421 * We put ourselves on the sleep queue and start our timeout 422 * before calling CURSIG, as we could stop there, and a wakeup 423 * or a SIGCONT (or both) could occur while we were stopped. 424 * A SIGCONT would cause us to be marked as SSLEEP 425 * without resuming us, thus we must be ready for sleep 426 * when CURSIG is called. If the wakeup happens while we're | 456 /* 457 * We put ourselves on the sleep queue and start our timeout 458 * before calling CURSIG, as we could stop there, and a wakeup 459 * or a SIGCONT (or both) could occur while we were stopped. 460 * A SIGCONT would cause us to be marked as SSLEEP 461 * without resuming us, thus we must be ready for sleep 462 * when CURSIG is called. If the wakeup happens while we're |
427 * stopped, p->p_wchan will be 0 upon return from CURSIG. | 463 * stopped, td->td_wchan will be 0 upon return from CURSIG. |
428 */ 429 if (catch) { 430 CTR3(KTR_PROC, "msleep caught: proc %p (pid %d, %s)", p, 431 p->p_pid, p->p_comm); | 464 */ 465 if (catch) { 466 CTR3(KTR_PROC, "msleep caught: proc %p (pid %d, %s)", p, 467 p->p_pid, p->p_comm); |
432 p->p_sflag |= PS_SINTR; | 468 td->td_flags |= TDF_SINTR; |
433 mtx_unlock_spin(&sched_lock); 434 PROC_LOCK(p); 435 sig = CURSIG(p); 436 mtx_lock_spin(&sched_lock); 437 PROC_UNLOCK_NOSWITCH(p); 438 if (sig != 0) { | 469 mtx_unlock_spin(&sched_lock); 470 PROC_LOCK(p); 471 sig = CURSIG(p); 472 mtx_lock_spin(&sched_lock); 473 PROC_UNLOCK_NOSWITCH(p); 474 if (sig != 0) { |
439 if (p->p_wchan != NULL) 440 unsleep(p); 441 } else if (p->p_wchan == NULL) | 475 if (td->td_wchan != NULL) 476 unsleep(td); 477 } else if (td->td_wchan == NULL) |
442 catch = 0; 443 } else 444 sig = 0; | 478 catch = 0; 479 } else 480 sig = 0; |
445 if (p->p_wchan != NULL) { 446 p->p_stat = SSLEEP; | 481 if (td->td_wchan != NULL) { 482 td->td_proc->p_stat = SSLEEP; |
447 p->p_stats->p_ru.ru_nvcsw++; 448 mi_switch(); 449 } | 483 p->p_stats->p_ru.ru_nvcsw++; 484 mi_switch(); 485 } |
450 CTR3(KTR_PROC, "msleep resume: proc %p (pid %d, %s)", p, p->p_pid, | 486 CTR3(KTR_PROC, "msleep resume: proc %p (pid %d, %s)", td, p->p_pid, |
451 p->p_comm); | 487 p->p_comm); |
452 KASSERT(p->p_stat == SRUN, ("running but not SRUN")); 453 p->p_sflag &= ~PS_SINTR; 454 if (p->p_sflag & PS_TIMEOUT) { 455 p->p_sflag &= ~PS_TIMEOUT; | 488 KASSERT(td->td_proc->p_stat == SRUN, ("running but not SRUN")); 489 td->td_flags &= ~TDF_SINTR; 490 if (td->td_flags & TDF_TIMEOUT) { 491 td->td_flags &= ~TDF_TIMEOUT; |
456 if (sig == 0) 457 rval = EWOULDBLOCK; | 492 if (sig == 0) 493 rval = EWOULDBLOCK; |
458 } else if (p->p_sflag & PS_TIMOFAIL) 459 p->p_sflag &= ~PS_TIMOFAIL; 460 else if (timo && callout_stop(&p->p_slpcallout) == 0) { | 494 } else if (td->td_flags & TDF_TIMOFAIL) 495 td->td_flags &= ~TDF_TIMOFAIL; 496 else if (timo && callout_stop(&td->td_slpcallout) == 0) { |
461 /* 462 * This isn't supposed to be pretty. If we are here, then 463 * the endtsleep() callout is currently executing on another 464 * CPU and is either spinning on the sched_lock or will be 465 * soon. If we don't synchronize here, there is a chance 466 * that this process may msleep() again before the callout 467 * has a chance to run and the callout may end up waking up 468 * the wrong msleep(). Yuck. 469 */ | 497 /* 498 * This isn't supposed to be pretty. If we are here, then 499 * the endtsleep() callout is currently executing on another 500 * CPU and is either spinning on the sched_lock or will be 501 * soon. If we don't synchronize here, there is a chance 502 * that this process may msleep() again before the callout 503 * has a chance to run and the callout may end up waking up 504 * the wrong msleep(). Yuck. 505 */ |
470 p->p_sflag |= PS_TIMEOUT; | 506 td->td_flags |= TDF_TIMEOUT; |
471 p->p_stats->p_ru.ru_nivcsw++; 472 mi_switch(); 473 } 474 mtx_unlock_spin(&sched_lock); 475 476 if (rval == 0 && catch) { 477 PROC_LOCK(p); 478 /* XXX: shouldn't we always be calling CURSIG() */ --- 26 unchanged lines hidden (view full) --- 505 * set timeout flag and undo the sleep. If proc 506 * is stopped, just unsleep so it will remain stopped. 507 * MP-safe, called without the Giant mutex. 508 */ 509static void 510endtsleep(arg) 511 void *arg; 512{ | 507 p->p_stats->p_ru.ru_nivcsw++; 508 mi_switch(); 509 } 510 mtx_unlock_spin(&sched_lock); 511 512 if (rval == 0 && catch) { 513 PROC_LOCK(p); 514 /* XXX: shouldn't we always be calling CURSIG() */ --- 26 unchanged lines hidden (view full) --- 541 * set timeout flag and undo the sleep. If proc 542 * is stopped, just unsleep so it will remain stopped. 543 * MP-safe, called without the Giant mutex. 544 */ 545static void 546endtsleep(arg) 547 void *arg; 548{ |
513 register struct proc *p; | 549 register struct thread *td = arg; |
514 | 550 |
515 p = (struct proc *)arg; 516 CTR3(KTR_PROC, "endtsleep: proc %p (pid %d, %s)", p, p->p_pid, 517 p->p_comm); | 551 CTR3(KTR_PROC, "endtsleep: thread %p (pid %d, %s)", td, td->td_proc->p_pid, 552 td->td_proc->p_comm); |
518 mtx_lock_spin(&sched_lock); 519 /* 520 * This is the other half of the synchronization with msleep() 521 * described above. If the PS_TIMEOUT flag is set, we lost the 522 * race and just need to put the process back on the runqueue. 523 */ | 553 mtx_lock_spin(&sched_lock); 554 /* 555 * This is the other half of the synchronization with msleep() 556 * described above. If the PS_TIMEOUT flag is set, we lost the 557 * race and just need to put the process back on the runqueue. 558 */ |
524 if ((p->p_sflag & PS_TIMEOUT) != 0) { 525 p->p_sflag &= ~PS_TIMEOUT; 526 setrunqueue(p); 527 } else if (p->p_wchan != NULL) { 528 if (p->p_stat == SSLEEP) 529 setrunnable(p); | 559 if ((td->td_flags & TDF_TIMEOUT) != 0) { 560 td->td_flags &= ~TDF_TIMEOUT; 561 setrunqueue(td); 562 } else if (td->td_wchan != NULL) { 563 if (td->td_proc->p_stat == SSLEEP) /* XXXKSE */ 564 setrunnable(td); |
530 else | 565 else |
531 unsleep(p); 532 p->p_sflag |= PS_TIMEOUT; 533 } else 534 p->p_sflag |= PS_TIMOFAIL; | 566 unsleep(td); 567 td->td_flags |= TDF_TIMEOUT; 568 } else { 569 td->td_flags |= TDF_TIMOFAIL; 570 } |
535 mtx_unlock_spin(&sched_lock); 536} 537 538/* 539 * Remove a process from its wait queue 540 */ 541void | 571 mtx_unlock_spin(&sched_lock); 572} 573 574/* 575 * Remove a process from its wait queue 576 */ 577void |
542unsleep(p) 543 register struct proc *p; | 578unsleep(struct thread *td) |
544{ 545 546 mtx_lock_spin(&sched_lock); | 579{ 580 581 mtx_lock_spin(&sched_lock); |
547 if (p->p_wchan != NULL) { 548 TAILQ_REMOVE(&slpque[LOOKUP(p->p_wchan)], p, p_slpq); 549 p->p_wchan = NULL; | 582 if (td->td_wchan != NULL) { 583 TAILQ_REMOVE(&slpque[LOOKUP(td->td_wchan)], td, td_slpq); 584 td->td_wchan = NULL; |
550 } 551 mtx_unlock_spin(&sched_lock); 552} 553 554/* 555 * Make all processes sleeping on the specified identifier runnable. 556 */ 557void 558wakeup(ident) 559 register void *ident; 560{ 561 register struct slpquehead *qp; | 585 } 586 mtx_unlock_spin(&sched_lock); 587} 588 589/* 590 * Make all processes sleeping on the specified identifier runnable. 591 */ 592void 593wakeup(ident) 594 register void *ident; 595{ 596 register struct slpquehead *qp; |
562 register struct proc *p; | 597 register struct thread *td; 598 struct proc *p; |
563 564 mtx_lock_spin(&sched_lock); 565 qp = &slpque[LOOKUP(ident)]; 566restart: | 599 600 mtx_lock_spin(&sched_lock); 601 qp = &slpque[LOOKUP(ident)]; 602restart: |
567 TAILQ_FOREACH(p, qp, p_slpq) { 568 if (p->p_wchan == ident) { 569 TAILQ_REMOVE(qp, p, p_slpq); 570 p->p_wchan = NULL; 571 if (p->p_stat == SSLEEP) { | 603 TAILQ_FOREACH(td, qp, td_slpq) { 604 p = td->td_proc; 605 if (td->td_wchan == ident) { 606 TAILQ_REMOVE(qp, td, td_slpq); 607 td->td_wchan = NULL; 608 if (td->td_proc->p_stat == SSLEEP) { |
572 /* OPTIMIZED EXPANSION OF setrunnable(p); */ | 609 /* OPTIMIZED EXPANSION OF setrunnable(p); */ |
573 CTR3(KTR_PROC, "wakeup: proc %p (pid %d, %s)", 574 p, p->p_pid, p->p_comm); 575 if (p->p_slptime > 1) 576 updatepri(p); 577 p->p_slptime = 0; 578 p->p_stat = SRUN; | 610 CTR3(KTR_PROC, "wakeup: thread %p (pid %d, %s)", 611 td, p->p_pid, p->p_comm); 612 if (td->td_ksegrp->kg_slptime > 1) 613 updatepri(td); 614 td->td_ksegrp->kg_slptime = 0; 615 td->td_kse->ke_slptime = 0; 616 td->td_proc->p_stat = SRUN; |
579 if (p->p_sflag & PS_INMEM) { | 617 if (p->p_sflag & PS_INMEM) { |
580 setrunqueue(p); 581 maybe_resched(p); | 618 setrunqueue(td); 619 maybe_resched(td->td_ksegrp); |
582 } else { 583 p->p_sflag |= PS_SWAPINREQ; 584 wakeup((caddr_t)&proc0); 585 } 586 /* END INLINE EXPANSION */ 587 goto restart; 588 } 589 } --- 6 unchanged lines hidden (view full) --- 596 * May wake more than one process if a target process is currently 597 * swapped out. 598 */ 599void 600wakeup_one(ident) 601 register void *ident; 602{ 603 register struct slpquehead *qp; | 620 } else { 621 p->p_sflag |= PS_SWAPINREQ; 622 wakeup((caddr_t)&proc0); 623 } 624 /* END INLINE EXPANSION */ 625 goto restart; 626 } 627 } --- 6 unchanged lines hidden (view full) --- 634 * May wake more than one process if a target process is currently 635 * swapped out. 636 */ 637void 638wakeup_one(ident) 639 register void *ident; 640{ 641 register struct slpquehead *qp; |
642 register struct thread *td; |
|
604 register struct proc *p; 605 606 mtx_lock_spin(&sched_lock); 607 qp = &slpque[LOOKUP(ident)]; 608 | 643 register struct proc *p; 644 645 mtx_lock_spin(&sched_lock); 646 qp = &slpque[LOOKUP(ident)]; 647 |
609 TAILQ_FOREACH(p, qp, p_slpq) { 610 if (p->p_wchan == ident) { 611 TAILQ_REMOVE(qp, p, p_slpq); 612 p->p_wchan = NULL; 613 if (p->p_stat == SSLEEP) { | 648 TAILQ_FOREACH(td, qp, td_slpq) { 649 p = td->td_proc; 650 if (td->td_wchan == ident) { 651 TAILQ_REMOVE(qp, td, td_slpq); 652 td->td_wchan = NULL; 653 if (td->td_proc->p_stat == SSLEEP) { |
614 /* OPTIMIZED EXPANSION OF setrunnable(p); */ 615 CTR3(KTR_PROC, "wakeup1: proc %p (pid %d, %s)", 616 p, p->p_pid, p->p_comm); | 654 /* OPTIMIZED EXPANSION OF setrunnable(p); */ 655 CTR3(KTR_PROC, "wakeup1: proc %p (pid %d, %s)", 656 p, p->p_pid, p->p_comm); |
617 if (p->p_slptime > 1) 618 updatepri(p); 619 p->p_slptime = 0; 620 p->p_stat = SRUN; | 657 if (td->td_ksegrp->kg_slptime > 1) 658 updatepri(td); 659 td->td_ksegrp->kg_slptime = 0; 660 td->td_kse->ke_slptime = 0; 661 td->td_proc->p_stat = SRUN; |
621 if (p->p_sflag & PS_INMEM) { | 662 if (p->p_sflag & PS_INMEM) { |
622 setrunqueue(p); 623 maybe_resched(p); | 663 setrunqueue(td); 664 maybe_resched(td->td_ksegrp); |
624 break; 625 } else { 626 p->p_sflag |= PS_SWAPINREQ; 627 wakeup((caddr_t)&proc0); 628 } 629 /* END INLINE EXPANSION */ 630 } 631 } 632 } 633 mtx_unlock_spin(&sched_lock); 634} 635 636/* 637 * The machine independent parts of mi_switch(). 638 */ 639void 640mi_switch() 641{ 642 struct timeval new_switchtime; | 665 break; 666 } else { 667 p->p_sflag |= PS_SWAPINREQ; 668 wakeup((caddr_t)&proc0); 669 } 670 /* END INLINE EXPANSION */ 671 } 672 } 673 } 674 mtx_unlock_spin(&sched_lock); 675} 676 677/* 678 * The machine independent parts of mi_switch(). 679 */ 680void 681mi_switch() 682{ 683 struct timeval new_switchtime; |
643 register struct proc *p = curproc; /* XXX */ | 684 struct thread *td = curthread; /* XXX */ 685 register struct proc *p = td->td_proc; /* XXX */ |
644#if 0 645 register struct rlimit *rlim; 646#endif 647 critical_t sched_crit; 648 u_int sched_nest; 649 650 mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); 651 --- 60 unchanged lines hidden (view full) --- 712 * Pick a new current process and record its start time. 713 */ 714 cnt.v_swtch++; 715 PCPU_SET(switchtime, new_switchtime); 716 CTR3(KTR_PROC, "mi_switch: old proc %p (pid %d, %s)", p, p->p_pid, 717 p->p_comm); 718 sched_crit = sched_lock.mtx_savecrit; 719 sched_nest = sched_lock.mtx_recurse; | 686#if 0 687 register struct rlimit *rlim; 688#endif 689 critical_t sched_crit; 690 u_int sched_nest; 691 692 mtx_assert(&sched_lock, MA_OWNED | MA_NOTRECURSED); 693 --- 60 unchanged lines hidden (view full) --- 754 * Pick a new current process and record its start time. 755 */ 756 cnt.v_swtch++; 757 PCPU_SET(switchtime, new_switchtime); 758 CTR3(KTR_PROC, "mi_switch: old proc %p (pid %d, %s)", p, p->p_pid, 759 p->p_comm); 760 sched_crit = sched_lock.mtx_savecrit; 761 sched_nest = sched_lock.mtx_recurse; |
720 p->p_lastcpu = p->p_oncpu; 721 p->p_oncpu = NOCPU; 722 p->p_sflag &= ~PS_NEEDRESCHED; | 762 td->td_lastcpu = td->td_kse->ke_oncpu; 763 td->td_kse->ke_oncpu = NOCPU; 764 td->td_kse->ke_flags &= ~KEF_NEEDRESCHED; |
723 cpu_switch(); | 765 cpu_switch(); |
724 p->p_oncpu = PCPU_GET(cpuid); | 766 td->td_kse->ke_oncpu = PCPU_GET(cpuid); |
725 sched_lock.mtx_savecrit = sched_crit; 726 sched_lock.mtx_recurse = sched_nest; | 767 sched_lock.mtx_savecrit = sched_crit; 768 sched_lock.mtx_recurse = sched_nest; |
727 sched_lock.mtx_lock = (uintptr_t)p; | 769 sched_lock.mtx_lock = (uintptr_t)td; |
728 CTR3(KTR_PROC, "mi_switch: new proc %p (pid %d, %s)", p, p->p_pid, 729 p->p_comm); 730 if (PCPU_GET(switchtime.tv_sec) == 0) 731 microuptime(PCPU_PTR(switchtime)); 732 PCPU_SET(switchticks, ticks); 733} 734 735/* 736 * Change process state to be runnable, 737 * placing it on the run queue if it is in memory, 738 * and awakening the swapper if it isn't in memory. 739 */ 740void | 770 CTR3(KTR_PROC, "mi_switch: new proc %p (pid %d, %s)", p, p->p_pid, 771 p->p_comm); 772 if (PCPU_GET(switchtime.tv_sec) == 0) 773 microuptime(PCPU_PTR(switchtime)); 774 PCPU_SET(switchticks, ticks); 775} 776 777/* 778 * Change process state to be runnable, 779 * placing it on the run queue if it is in memory, 780 * and awakening the swapper if it isn't in memory. 781 */ 782void |
741setrunnable(p) 742 register struct proc *p; | 783setrunnable(struct thread *td) |
743{ | 784{ |
744 | 785 struct proc *p = td->td_proc; |
745 mtx_lock_spin(&sched_lock); 746 switch (p->p_stat) { | 786 mtx_lock_spin(&sched_lock); 787 switch (p->p_stat) { |
788 case SZOMB: /* not a thread flag XXXKSE */ 789 panic("setrunnabl(1)"); 790 } 791 switch (td->td_proc->p_stat) { |
|
747 case 0: 748 case SRUN: | 792 case 0: 793 case SRUN: |
749 case SZOMB: | |
750 case SWAIT: 751 default: | 794 case SWAIT: 795 default: |
752 panic("setrunnable"); | 796 panic("setrunnable(2)"); |
753 case SSTOP: 754 case SSLEEP: /* e.g. when sending signals */ | 797 case SSTOP: 798 case SSLEEP: /* e.g. when sending signals */ |
755 if (p->p_sflag & PS_CVWAITQ) 756 cv_waitq_remove(p); | 799 if (td->td_flags & TDF_CVWAITQ) 800 cv_waitq_remove(td); |
757 else | 801 else |
758 unsleep(p); | 802 unsleep(td); |
759 break; 760 761 case SIDL: 762 break; 763 } | 803 break; 804 805 case SIDL: 806 break; 807 } |
764 p->p_stat = SRUN; 765 if (p->p_slptime > 1) 766 updatepri(p); 767 p->p_slptime = 0; | 808 td->td_proc->p_stat = SRUN; 809 if (td->td_ksegrp->kg_slptime > 1) 810 updatepri(td); 811 td->td_ksegrp->kg_slptime = 0; 812 td->td_kse->ke_slptime = 0; |
768 if ((p->p_sflag & PS_INMEM) == 0) { 769 p->p_sflag |= PS_SWAPINREQ; 770 wakeup((caddr_t)&proc0); 771 } else { | 813 if ((p->p_sflag & PS_INMEM) == 0) { 814 p->p_sflag |= PS_SWAPINREQ; 815 wakeup((caddr_t)&proc0); 816 } else { |
772 setrunqueue(p); 773 maybe_resched(p); | 817 setrunqueue(td); 818 maybe_resched(td->td_ksegrp); |
774 } 775 mtx_unlock_spin(&sched_lock); 776} 777 778/* 779 * Compute the priority of a process when running in user mode. 780 * Arrange to reschedule if the resulting priority is better 781 * than that of the current process. 782 */ 783void | 819 } 820 mtx_unlock_spin(&sched_lock); 821} 822 823/* 824 * Compute the priority of a process when running in user mode. 825 * Arrange to reschedule if the resulting priority is better 826 * than that of the current process. 827 */ 828void |
784resetpriority(p) 785 register struct proc *p; | 829resetpriority(kg) 830 register struct ksegrp *kg; |
786{ 787 register unsigned int newpriority; 788 789 mtx_lock_spin(&sched_lock); | 831{ 832 register unsigned int newpriority; 833 834 mtx_lock_spin(&sched_lock); |
790 if (p->p_pri.pri_class == PRI_TIMESHARE) { 791 newpriority = PUSER + p->p_estcpu / INVERSE_ESTCPU_WEIGHT + 792 NICE_WEIGHT * (p->p_nice - PRIO_MIN); | 835 if (kg->kg_pri.pri_class == PRI_TIMESHARE) { 836 newpriority = PUSER + kg->kg_estcpu / INVERSE_ESTCPU_WEIGHT + 837 NICE_WEIGHT * (kg->kg_nice - PRIO_MIN); |
793 newpriority = min(max(newpriority, PRI_MIN_TIMESHARE), 794 PRI_MAX_TIMESHARE); | 838 newpriority = min(max(newpriority, PRI_MIN_TIMESHARE), 839 PRI_MAX_TIMESHARE); |
795 p->p_pri.pri_user = newpriority; | 840 kg->kg_pri.pri_user = newpriority; |
796 } | 841 } |
797 maybe_resched(p); | 842 maybe_resched(kg); |
798 mtx_unlock_spin(&sched_lock); 799} 800 801/* ARGSUSED */ 802static void 803sched_setup(dummy) 804 void *dummy; 805{ --- 16 unchanged lines hidden (view full) --- 822 * quite quickly when the process is running (linearly), and decays 823 * away exponentially, at a rate which is proportionally slower when 824 * the system is busy. The basic principle is that the system will 825 * 90% forget that the process used a lot of CPU time in 5 * loadav 826 * seconds. This causes the system to favor processes which haven't 827 * run much recently, and to round-robin among other processes. 828 */ 829void | 843 mtx_unlock_spin(&sched_lock); 844} 845 846/* ARGSUSED */ 847static void 848sched_setup(dummy) 849 void *dummy; 850{ --- 16 unchanged lines hidden (view full) --- 867 * quite quickly when the process is running (linearly), and decays 868 * away exponentially, at a rate which is proportionally slower when 869 * the system is busy. The basic principle is that the system will 870 * 90% forget that the process used a lot of CPU time in 5 * loadav 871 * seconds. This causes the system to favor processes which haven't 872 * run much recently, and to round-robin among other processes. 873 */ 874void |
830schedclock(p) 831 struct proc *p; | 875schedclock(td) 876 struct thread *td; |
832{ | 877{ |
878 struct kse *ke = td->td_kse; 879 struct ksegrp *kg = td->td_ksegrp; |
|
833 | 880 |
834 p->p_cpticks++; 835 p->p_estcpu = ESTCPULIM(p->p_estcpu + 1); 836 if ((p->p_estcpu % INVERSE_ESTCPU_WEIGHT) == 0) { 837 resetpriority(p); 838 if (p->p_pri.pri_level >= PUSER) 839 p->p_pri.pri_level = p->p_pri.pri_user; | 881 if (td) { 882 ke->ke_cpticks++; 883 kg->kg_estcpu = ESTCPULIM(kg->kg_estcpu + 1); 884 if ((kg->kg_estcpu % INVERSE_ESTCPU_WEIGHT) == 0) { 885 resetpriority(td->td_ksegrp); 886 if (kg->kg_pri.pri_level >= PUSER) 887 kg->kg_pri.pri_level = kg->kg_pri.pri_user; 888 } 889 } else { 890 panic("schedclock"); |
840 } 841} 842 843/* 844 * General purpose yield system call 845 */ 846int | 891 } 892} 893 894/* 895 * General purpose yield system call 896 */ 897int |
847yield(struct proc *p, struct yield_args *uap) | 898yield(struct thread *td, struct yield_args *uap) |
848{ | 899{ |
849 p->p_retval[0] = 0; | |
850 | 900 |
901 struct ksegrp *kg = td->td_ksegrp; 902 td->td_retval[0] = 0; 903 |
|
851 mtx_lock_spin(&sched_lock); 852 mtx_assert(&Giant, MA_NOTOWNED); 853#if 0 854 DROP_GIANT_NOSWITCH(); 855#endif | 904 mtx_lock_spin(&sched_lock); 905 mtx_assert(&Giant, MA_NOTOWNED); 906#if 0 907 DROP_GIANT_NOSWITCH(); 908#endif |
856 p->p_pri.pri_level = PRI_MAX_TIMESHARE; 857 setrunqueue(p); 858 p->p_stats->p_ru.ru_nvcsw++; | 909 kg->kg_pri.pri_level = PRI_MAX_TIMESHARE; 910 setrunqueue(td); 911 kg->kg_proc->p_stats->p_ru.ru_nvcsw++; |
859 mi_switch(); 860 mtx_unlock_spin(&sched_lock); 861#if 0 862 PICKUP_GIANT(); 863#endif 864 865 return (0); 866} 867 | 912 mi_switch(); 913 mtx_unlock_spin(&sched_lock); 914#if 0 915 PICKUP_GIANT(); 916#endif 917 918 return (0); 919} 920 |