Переключение контекста

Функция context_switch (), вызываемая из schedule () в /kernel/sched. с, вы-шадняет специфическую для системы работу по переключению окружения памяти и состояния процесса. На абстрактном уровне context_switch переключает текущую за-JB4Y и следующую задачу. Функция context_switch () начинает выполнение следующей задачи и возвращает указатель на структуру задачи, которая выполнялась до вызова:

ismel/sched. с
1143 /*
1149 * context_switch - переключение на новый ММ и новое
1X53 * состояние регистра потока.
1151 */
1152 static inline
1153 task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)
1154 {
1155 struct mm_struct *mm = next->mm;
1155 struct mm_struct *oldmm = prev->active_mm;
1153 switch_itim(oldmm, mm, next) ;
1172 switch_to(prev, next, prev); Здесь мы описываем две задачи context_switch: переключение виртуального отображения памяти и переключение структуры задачи/потока. За выполнение первой задачи отвечает switch_mm() с применением множества аппаратно-зависимых управляющих памятью структур и регистров:

/include/asm-i386/mmu_context.h
026 static inline void switch_mm(struct mm_struct *prev,
27 struct mm_struct *next,
28 struct task_struct *tsk)
029 {
030 int cpu = smp_processor_id();
031
32 if (likely(prev != next)) {
33 /* остановка сброса ipis для предыдущего mm */
34 cpu_clear(cpu, prev->cpu_vm_mask);
035 #ifdef CONFIG_SMP
36 cpu_tlbstate[cpu].state = TLBSTATE_OK;
37 cpu_tlbstate[cpu].active_mm = next;
038 #endif
039 cpu_set(cpu, next->cpu_vm_mask);
040
41 /* Перезагрузка таблицы страниц */
42 load_cr3(next->pgd); 043

44 /*
45 * загрузка LDT, если LDT отличается:
46 */
047 if (unlikely(prev->context.ldt != next->context.ldt))
048 load_LDT_nolock(&next->context, cpu) ,-
49 }
50 #ifdef CONFIG_SMP
051 else {

Строка 39
Связывает новую задачу с текущим процессором. Строка 42
Код переключения контекста памяти использует аппаратный х86-регистр, хранящий базовый адрес всех виртуальных операций для данного процесса. Новый глобальный описатель страницы загружается сюда из next->pgd.
Большинство процессов разделяют один и тот же LDT. Если процессу требуется другой LDT, он загружается сюда из новой структуры next->context.
Другая половина функции context_switch () находится в /kernel/sched. с,
: вызывается макрос switch_to (), который вызывает С-функцию switch_to ().
ектурные ограничения независимы от архитектурных зависимостей для х86- и РРС-сов switch_to