Linux Kernel (Ядро линукса) (часть 1)


Действия, выполняемые функцией scheduled после переключения процесса

Инструкции фуНКЦИЙ context switcho И schedule (), идущие ПОСЛе ВЫЗОВа макроса switch to, не будут тут же выполнены процессом next. Их выполнит процесс prev позже, когда планировщик снова выберет его для выполнения. Однако в тот момент локальная переменная prev будет указывать не на первый процесс, который подлежал замене, когда мы начали описание функции schedule о, а на процесс, который был заменен нашим первым процессом prev, когда планировщик снова выбрал его. Первыми инструкциями после переключения процесса будут такие:
barrier();
finish_task_switch(prev);
Сразу после вызова функции context switch из функции schedule о макрос barrier возвращает оптимизационный барьер для кода Затем вызывается функция finish_task_switch():
mm = this_rq ()->prev_mm; this_rq()->prev_mm = NULL;
prev_task_flags = prev->flags; spin_unlock_irq(&this_rq()->lock); if (mm)
mmdrop (mm) ; if (prev_task_flags & PF_DEAD) put_task_struct(prev);
Если процесс prev является потоком ядра, поле prev mm очереди на выполнение хранит адрес дескриптора памяти, представленной процессу prev. Как мы увидим в главе 9, функция mmdrop уменьшает счетчик обращений дескриптора памяти, а если счетчик достигнет нуля (что вполне вероятно, поскольку prev является процессом-зомби), функция освободит дескриптор вместе с ассоциированными Таблицами Страниц и областями виртуальной памяти.
Функция finish task switcho также освобождает спин-блокировку очереди на выполнение и включает локальные прерывания. Затем она проверяет, является ли prev процессом-зомби, удаляемым в этот момент из системы и, если это действительно так, вызывает функцию put task struct о, чтобы освободить счетчик ссылок дескриптора процесса и сбросить все оставшиеся ссылки на процесс.

Заключительными инструкциями функции schedule являются следующие:

finish_schedule:prev = current; if (prev->lock_depth >= 0)
reacquire_kernel_lock();preempt_enable_no_resched();
if (test_bit(TIF_NEED_RESCHED, ¤t_thread_info()->flags) goto need_resched; return;
Здесь видно, что функция schedule о при необходимости заново получает глобальную блокировку ядра, заново включает вытеснение в ядре и проверяет, установил ли какой-нибудь другой процесс флаг tif need resched у текущего процесса. Если флаг установлен, функция schedule о выполняется еще раз с самого начала; в противном случае она завершает работу.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть...

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...