алгоритм vfault /* обработка отказа из-за отсутствия (недоступности) данных */ входная информация: адрес, по которому получен отказ выходная информация: отсутствует { найти область, запись в таблице страниц, дескриптор дис- кового блока, связанные с адресом, по которому получен отказ, заблокировать область; если (адрес не принадлежит виртуальному адресному прост- ранству процесса) { послать сигнал (SIGSEGV: нарушение сегментации) про- цессу; перейти на out; } если (адрес указан неверно) /* возможно, процесс нахо- дился в состоянии при- останова */ перейти на out; если (страница имеется в кэше) { убрать страницу из кэша; поправить запись в таблице страниц; выполнять пока (содержимое страницы не станет доступ- ным) /* другой процесс получил такой же отказ, * но раньше */ приостановиться; } в противном случае /* страница отсутствует в кэше */ { назначить области новую страницу; поместить новую страницу в кэш, откорректировать за- пись в таблице pfdata; если (страница ранее не загружалась в память и имеет пометку "обнуляемая при обращении") очистить содержимое страницы; в противном случае { считать виртуальную страницу с устройства выгруз- ки или из исполняемого файла; приостановиться (до завершения ввода-вывода); } возобновить процессы (ожидающие загрузки содержимого страницы); } установить бит доступности страницы; сбросить бит модификации и "возраст" страницы; пересчитать приоритет процесса; out: снять блокировку с области; } |
При обработке отказов из-за недоступности данных ядро не всегда прибегает к выполнению операции ввода-вывода, даже когда из дескриптора дискового блока видно, что страница загружена (в случае 2). Может случиться так, что ядро после выгрузки содержимого физической страницы так и не переприсвоило ее или же какой-то иной процесс в результате отказа загрузил содержимое виртуальной страницы в другую физическую страницу. В любом случае программа обработки отказа обнаруживает страницу в кэше, в качестве ключа используя номер блока в дескрипторе дискового блока. Она перенастраивает соответствующую запись в таблице страниц на только что найденную страницу, увеличивает значение счетчика ссылок на страницу и в случае необходимости убирает страницу из списка свободных страниц. Предположим, к примеру, что процесс получил отказ при обращении к виртуальному адресу 64К (Рисунок 9.22). Просматривая кэш, ядро устанавливает, что страничный блок с номером 1861 связан с дисковым блоком 1206. Ядро перенастраивает запись таблицы страниц с виртуальным адресом 64К на страницу с номером 1861, устанавливает бит доступности и передает управление программе обработки отказа. Таким образом, номер дискового блока связывает вместе записи таблицы страниц и таблицы pfdata, чем и объясняется его запоминание в обеих таблицах.