RU/2: Форум. Общение пользователей и разработчиков OS/2 (eCS). : Multithreading (VIII)


Список сообщений | Написать новое | Ответить на сообщение | Домой Поиск:
Предыдущее сообщение | Следующее сообщение
From : ???
To : All
Subj : Multithreading (VIII)

Context Switching within the Kernel Mode

Context switching refers to the mechanism used by the kernel to stop running one thread
and to start another. The OS/2 dispatcher implements a policy of context switching only
when a thread attempts to exit the kernel(ExitKMode) or when a thread in the kernel
blocks waiting on an event resource.

Therefore, the ExitKMode routine becomes the single locus of control for forced actions
that a thread must perform, such as context switching, signal dispatching, and
termination.

A global flag variable called ReSched is shared between the dispatcher and the scheduler.
ReSched indicates whether there is potentially a thread of priority higher than that of the
current thread that has been made ready to run.This part of the ExitKmode routine is
called whenever a thread attempts to exit kernel mode checks the ReSched flag.

If the ReSched flag is set, the SchedNext routine of the dispatcher is called to switch out
the current running thread in order to run the highest-priority ready thread in the system.
SchedNext is the actual context switch routine of the system, and is the only place that a
thread switch occurs in the kernel. It is called only from ExitKMode and from ProcBlock;
the latter routine is used when a thread in the kernel blocks and gives up the processor.

The thread that is currently running when SchedNext is invoked is called the "outgoing
thread", and the thread to which SchedNext ultimately switsches is called the "incoming
thread". Only outgoing threads call SchedNext, and only incoming threads returns from
SchedNext. We now look in more detail at how the SchedNext routine performs the
context switch.

SchedNext begins executing by calling the GetNextRunner routine in the scheduler compo-
nent to dertermine the highest-priority thread that should be new running(incoming)
thread. If the outgoing thread is the same as the incoming thread, SchedNext merely
returns, and the current thread continues executing. If the outgoing thread is different
from the incoming thread, SchedNext performs a context switch.

If GetNextRunner indicates that there are no threads in the system that are ready to run,
it executes a loop known a the "idle loop". The idle loop is executed when all threads in
the system are blocked on some external event. This implies that there is no background
activity and that there are no user requests occuring via keyboard or mouse - the entire
system is waiting. The idle loop exists whithin SchedNext, and consists of polling the
RedSched flag with interrupts enabled.

When an interrupt occurs that makes a blocked thread redy to run, the thread running
in the idle loop will exit, will call GetNextRunner again, and will continue executing
SchedNext to switch in the ready-to-run thread.

Once a new thread to run has been selected, SchedNext determines whether the outgoing
thread is within the same process as the incoming thread, or is within a different process.
If the incoming and outgoing threads are in different processes, SchedNext must switch
the process context(PTDAs, process virtual adress spaces, etc. see:
m019634.html ) and the thread context. If both threads are within
the same process, only the thread context must be switched.

The actual switching of the process context entails changing the current PTDA, and
calling the memory manager to switch process virtual address spaces. Switching a thread
context entails setting the current thread variable in the current PTDA, changing kernel
stacks, and resuming execution at a known place in SchedNext at which all threads
resume running when they are outgoing. Since the task-state segment(TSS) of the
system contains the address of the current thread's kernel stack, it also must be edited
during a context switch to ensure that future priviledge level transitions by the running
thread use the proper kernel stack.

An interesting caveat in the OS/2 context switching model is that there is no explicit
"save/store" instruction or routine used to save all registers from one thread and restore
the registers for another. Although the TSS construct of the 80x86 tasking architecture
provides this functions, OS/2 does not utilize it except for the minimum of having a single
TSS for supporting priviledge level transitions.

The TSS switching feature of 80x86 processors provides a mechanism for performing a
save/restore for the entire register set in a single instruction. Since this set includes all
segment registers on 80286 architectures, and also the paging registers on the 80336
and 80486, the TSS switch is slow due to flushing of the segment register caches,
flushing of the translation lookaside buffer used for page transition, and the protection
checks that occur as the segment registers are loaded.

When contrasted with the OS/2 context switch model, the overhead is not required for
several reasons. The thread's user mode register set is saved on the kernel stack when
the thread enters kernel mode, and is restored when a thread exits kernel mode. Within
SchedNext, only the process virtual address space needs to be switched (and only in the
process switch case), since both the outgoing and incoming threads, are executing in the
system virtual address space.

Also, all threads resume execution in SchedNext at a fixed point where known values are
loaded into the registers - the thread do not rely on any saved state to resume their
execution in the kernel, since they are on the kernel stack already. This results in much
faster context switching compared to the TSS switching model. It also uses less memory,
since the TSS model requires a TSS to be allocated and managed for each thread in the
system.

This theme will be continued concerning system API handling, interrupts and exceptions
in further lessions.





Fri 02 Jan 2004 15:49 Mozilla/4.61 [en] (OS/2; U)




Programmed by Dmitri Maximovich, Dmitry I. Platonoff, Eugen Kuleshov.
25.09.99 (c) 1999, RU/2. All rights reserved.
Rewritten by Dmitry Ban. All rights ignored.