Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/sched_4bsd.c
Show First 20 Lines • Show All 1,656 Lines • ▼ Show 20 Lines | while (sched_runnable() == 0) { | ||||
stat->idlecalls++; | stat->idlecalls++; | ||||
} | } | ||||
mtx_lock_spin(&sched_lock); | mtx_lock_spin(&sched_lock); | ||||
mi_switch(SW_VOL | SWT_IDLE); | mi_switch(SW_VOL | SWT_IDLE); | ||||
} | } | ||||
} | } | ||||
static void | |||||
sched_throw_tail(struct thread *td) | |||||
{ | |||||
mtx_assert(&sched_lock, MA_OWNED); | |||||
KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count")); | |||||
cpu_throw(td, choosethread()); /* doesn't return */ | |||||
} | |||||
/* | /* | ||||
* A CPU is entering for the first time or a thread is exiting. | * A CPU is entering for the first time. | ||||
*/ | */ | ||||
void | void | ||||
sched_throw(struct thread *td) | sched_ap_entry(void) | ||||
{ | { | ||||
/* | /* | ||||
* Correct spinlock nesting. The idle thread context that we are | * Correct spinlock nesting. The idle thread context that we are | ||||
* borrowing was created so that it would start out with a single | * borrowing was created so that it would start out with a single | ||||
* spin lock (sched_lock) held in fork_trampoline(). Since we've | * spin lock (sched_lock) held in fork_trampoline(). Since we've | ||||
* explicitly acquired locks in this function, the nesting count | * explicitly acquired locks in this function, the nesting count | ||||
* is now 2 rather than 1. Since we are nested, calling | * is now 2 rather than 1. Since we are nested, calling | ||||
* spinlock_exit() will simply adjust the counts without allowing | * spinlock_exit() will simply adjust the counts without allowing | ||||
* spin lock using code to interrupt us. | * spin lock using code to interrupt us. | ||||
*/ | */ | ||||
if (td == NULL) { | |||||
mtx_lock_spin(&sched_lock); | mtx_lock_spin(&sched_lock); | ||||
spinlock_exit(); | spinlock_exit(); | ||||
PCPU_SET(switchtime, cpu_ticks()); | PCPU_SET(switchtime, cpu_ticks()); | ||||
PCPU_SET(switchticks, ticks); | PCPU_SET(switchticks, ticks); | ||||
} else { | |||||
lock_profile_release_lock(&sched_lock.lock_object, true); | sched_throw_tail(NULL); | ||||
} | |||||
/* | |||||
* A thread is exiting. | |||||
*/ | |||||
void | |||||
sched_throw(struct thread *td) | |||||
{ | |||||
MPASS(td != NULL); | |||||
MPASS(td->td_lock == &sched_lock); | MPASS(td->td_lock == &sched_lock); | ||||
lock_profile_release_lock(&sched_lock.lock_object, true); | |||||
kib: I would group this MPASS together with td != NULL | |||||
td->td_lastcpu = td->td_oncpu; | td->td_lastcpu = td->td_oncpu; | ||||
td->td_oncpu = NOCPU; | td->td_oncpu = NOCPU; | ||||
} | |||||
mtx_assert(&sched_lock, MA_OWNED); | sched_throw_tail(td); | ||||
KASSERT(curthread->td_md.md_spinlock_count == 1, ("invalid count")); | |||||
cpu_throw(td, choosethread()); /* doesn't return */ | |||||
} | } | ||||
void | void | ||||
sched_fork_exit(struct thread *td) | sched_fork_exit(struct thread *td) | ||||
{ | { | ||||
/* | /* | ||||
* Finish setting up thread glue so that it begins execution in a | * Finish setting up thread glue so that it begins execution in a | ||||
▲ Show 20 Lines • Show All 103 Lines • Show Last 20 Lines |
I would group this MPASS together with td != NULL