diff options
| author | Ingo Molnar <mingo@elte.hu> | 2002-06-12 22:56:29 +0200 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2002-06-12 22:56:29 +0200 |
| commit | 873cbfcf90a4d207e26070605c2802b6569e0a0c (patch) | |
| tree | 561751542c328354baa652fb4eef6df4fafd8a9f /include/linux | |
| parent | b533e8126153a6a56b7eb40961de0a218023a76b (diff) | |
- i've extended the scheduler context-switch mechanism with the following
per-arch defines:
prepare_arch_schedule(prev_task);
finish_arch_schedule(prev_task);
prepare_arch_switch(rq);
finish_arch_switch(rq);
- plus switch_to() takes 3 parameters again:
switch_to(prev, next, last);
- schedule_tail() has the 'prev' task parameter again, it must be passed
over in switch_to() and passed in to the fork() startup path.
architectures that need to unlock the runqueue before doing the switch can
do the following:
#define prepare_arch_schedule(prev) task_lock(prev)
#define finish_arch_schedule(prev) task_unlock(prev)
#define prepare_arch_switch(rq) spin_unlock(&(rq)->lock)
#define finish_arch_switch(rq) __sti()
this way the task-lock makes sure that a task is not scheduled on some
other CPU before the switch-out finishes, but the runqueue lock is
dropped. (Local interrupts are kept disabled in this variant, just to
exclude things like TLB flushes - if that matters.)
architectures that can hold the runqueue lock during context-switch can do
the following simplification:
#define prepare_arch_schedule(prev) do { } while(0)
#define finish_arch_schedule(prev) do { } while(0)
#define prepare_arch_switch(rq) do { } while(0)
#define finish_arch_switch(rq) spin_unlock_irq(&(rq)->lock)
further optimizations possible in the 'simple' variant:
- an architecture does not have to handle the 'last' parameter in
switch_to() if the 'prev' parameter is unused in finish_arch_schedule().
This way the inlined return value of context_switch() too gets optimized
away at compile-time.
- an architecture does not have to pass the 'prev' pointer to
schedule_tail(), if the 'prev' parameter is unused in
finish_arch_schedule().
the x86 architecture makes use of these optimizations.
Via this solution we have a reasonably flexible context-switch setup which
falls back to the current (faster) code on x86, but on other platforms the
runqueue lock can be dropped before doing the context-switch as well.
Ingo
NOTE: i have coded and tested the 'complex' variant on x86 as well to make
sure it works for you on Sparc64 - but since x86's switch_mm() is
not too subtle it can use the simpler variant. [ The following
things had to be done to make x86 arch use the complex variant: the
4 complex macros have to be used in system.h, entry.S has to
'pushl %ebx' and 'addl $4, %esp' around the call to schedule_tail(),
and switch_to() had to be reverted to the 3-parameter variant
present in the 2.4 kernels.
NOTE2: prepare_to_switch() functionality has been moved into the
prepare_arch_switch() macro.
NOTE3: please use macros for prepare|finish_arch_switch() so that we can
keep the scheduler data structures internal to sched.c.
Diffstat (limited to 'include/linux')
0 files changed, 0 insertions, 0 deletions
