Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/sched_ule.c
Show First 20 Lines • Show All 1,738 Lines • ▼ Show 20 Lines | schedinit(void) | ||||
ts0 = td_get_sched(&thread0); | ts0 = td_get_sched(&thread0); | ||||
ts0->ts_ltick = ticks; | ts0->ts_ltick = ticks; | ||||
ts0->ts_ftick = ticks; | ts0->ts_ftick = ticks; | ||||
ts0->ts_slice = 0; | ts0->ts_slice = 0; | ||||
ts0->ts_cpu = curcpu; /* set valid CPU number */ | ts0->ts_cpu = curcpu; /* set valid CPU number */ | ||||
} | } | ||||
/* | /* | ||||
* schedinit_ap() is needed prior to calling sched_throw(NULL) to ensure that | |||||
markj: You might consider having a comment here to explain why this is needed before sched_throw(NULL). | |||||
* the pcpu requirements are met for any calls in the period between curthread | |||||
* initialization and sched_throw(). One can safely add threads to the queue | |||||
* before sched_throw(), for instance, as long as the thread lock is setup | |||||
* correctly. | |||||
* | |||||
* TDQ_SELF() relies on the below sched pcpu setting; it may be used only | |||||
* after schedinit_ap(). | |||||
*/ | |||||
void | |||||
schedinit_ap(void) | |||||
{ | |||||
#ifdef SMP | |||||
PCPU_SET(sched, DPCPU_PTR(tdq)); | |||||
#endif | |||||
PCPU_GET(idlethread)->td_lock = TDQ_LOCKPTR(TDQ_SELF()); | |||||
} | |||||
/* | |||||
* This is only somewhat accurate since given many processes of the same | * This is only somewhat accurate since given many processes of the same | ||||
* priority they will switch when their slices run out, which will be | * priority they will switch when their slices run out, which will be | ||||
* at most sched_slice stathz ticks. | * at most sched_slice stathz ticks. | ||||
*/ | */ | ||||
int | int | ||||
sched_rr_interval(void) | sched_rr_interval(void) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,213 Lines • ▼ Show 20 Lines | |||||
* A CPU is entering for the first time or a thread is exiting. | * A CPU is entering for the first time or a thread is exiting. | ||||
*/ | */ | ||||
void | void | ||||
sched_throw(struct thread *td) | sched_throw(struct thread *td) | ||||
{ | { | ||||
struct thread *newtd; | struct thread *newtd; | ||||
struct tdq *tdq; | struct tdq *tdq; | ||||
if (__predict_false(td == NULL)) { | |||||
#ifdef SMP | |||||
PCPU_SET(sched, DPCPU_PTR(tdq)); | |||||
#endif | |||||
/* Correct spinlock nesting and acquire the correct lock. */ | |||||
tdq = TDQ_SELF(); | tdq = TDQ_SELF(); | ||||
Done Inline ActionsI suspect this note would be more appropriate in the comment above schedinit_ap() kib: I suspect this note would be more appropriate in the comment above schedinit_ap() | |||||
if (__predict_false(td == NULL)) { | |||||
TDQ_LOCK(tdq); | TDQ_LOCK(tdq); | ||||
Done Inline ActionsI think 'the correct' part of the comment is not quite needed anymore. Perhaps the whole part about lock can be dropped, and 'correct spinlock nesting' moved just to spinlock_exit() line. kib: I think 'the correct' part of the comment is not quite needed anymore. Perhaps the whole part… | |||||
/* Correct spinlock nesting. */ | |||||
spinlock_exit(); | spinlock_exit(); | ||||
PCPU_SET(switchtime, cpu_ticks()); | PCPU_SET(switchtime, cpu_ticks()); | ||||
PCPU_SET(switchticks, ticks); | PCPU_SET(switchticks, ticks); | ||||
PCPU_GET(idlethread)->td_lock = TDQ_LOCKPTR(tdq); | |||||
} else { | } else { | ||||
tdq = TDQ_SELF(); | |||||
THREAD_LOCK_ASSERT(td, MA_OWNED); | THREAD_LOCK_ASSERT(td, MA_OWNED); | ||||
THREAD_LOCKPTR_ASSERT(td, TDQ_LOCKPTR(tdq)); | THREAD_LOCKPTR_ASSERT(td, TDQ_LOCKPTR(tdq)); | ||||
Not Done Inline ActionsI suspect that this LOCKPTR_ASSERT() is now valid always. kib: I suspect that this LOCKPTR_ASSERT() is now valid always. | |||||
Done Inline Actionstd == NULL in the other path, though. kevans: `td == NULL` in the other path, though. | |||||
tdq_load_rem(tdq, td); | tdq_load_rem(tdq, td); | ||||
td->td_lastcpu = td->td_oncpu; | td->td_lastcpu = td->td_oncpu; | ||||
td->td_oncpu = NOCPU; | td->td_oncpu = NOCPU; | ||||
thread_lock_block(td); | thread_lock_block(td); | ||||
} | } | ||||
newtd = choosethread(); | newtd = choosethread(); | ||||
spinlock_enter(); | spinlock_enter(); | ||||
TDQ_UNLOCK(tdq); | TDQ_UNLOCK(tdq); | ||||
▲ Show 20 Lines • Show All 214 Lines • Show Last 20 Lines |
You might consider having a comment here to explain why this is needed before sched_throw(NULL).