Ю. Вахалия - UNIX изнутри (2003) (1114670), страница 17
Текст из файла (страница 17)
В системах УМ1Х каждому типу прерывания принято назначать уровень приоритета прерывания (!пгеггцрс рйойгу !ече1, !р1). В первых реализациях системы уровеныр! находился в пределах от О до 7. В ОС ВоВ значение 1р1 возросло до Π— 31. Регистр состояния процессора обычно содержит битовые поля, в которых хранится текущий (а иногда и предыдущий) гр1'. Номера приоритетов прерываний не одинаковы, так как зависят не только от конкретной реализации системы ()Ы!Х, но и от различия в архитектуре обору- ' Некоторые процессоры, например !псе! 80х86, не поддерживагот приоритеты прерываний на аппаратном уровне. В таких системах необходимо реализовывать уровни гр1 программно. Эта проблема будет затронута в дальнейшем в упражнениях.
2.4. Выполнение в режиме ядра 7Ъ Таблица 2. т. Установка уровней приоритетов прерываний в системах 4.3ВЗР и ЗУВ4 4.3ВЗР ЗЧВ4 Назначение Разрешить все прерывания Блокировать функции, планируемые таймерами Блокировать функционирование сетевых протоколов Блокировать прерывания ЗТВЕАМЗ Блокировать прерывания терминала Блокировать дисковые прерывания Блокировать прерывания сетевых устройств Блокировать прерывание аппаратного таймера Запретить обработку всех прерываний Восстановить 1р! в предыдущее сохраненное значение зрй или зр!Ьазе зрцнлеоис 5Р!О трцоттс!оск 5р!лес 5Р!зтг зр!цу зрЫВк 5Р!СсУ 5Р!Ь!с 5РЗПЗР 5Р!с!сск яр!"'9" 5Р!х зрп или 5РВ1 5Р!х После того как в системе происходит прерывание, дальнейшие действия зависят от его уровня: если уровеныр1 окажется выше текущего, то действия приостанавливаются, и запускается обработчик уже нового прерывания.
Обработчик начинает свою работу на новом уровне !р1. После завершения процедуры обслуживания прерывания уровень 1р! понижается до предыдущего значения (которое хранится в предыдущем слове состояния процессора в стеке прерываний), и ядро продолжает обработку текущего прерванного процесса. Если ядро получает прерывание, имеющее уровень более низкий или равный текущему значению !р1, то такое прерывание не будет обрабатываться незамедлительно. Оно будет сохранено в регистре прерываний и обработано после соответствующего изменения уровня 1р!. Алгоритм обработки прерываний показан на рис. 2.5.
Уровни 1р1 сравниваются и устанавливаются на аппаратном уровне в зависимости от архитектуры конкретного компьютера. Ядро системы 13Ь!1Х имеет механизмы четкого определения или установки уровней !р1. К примеру, ядро может повысить уровень !р! с целью блокировки прерываний на время выполнения некоторых критичных инструкций. Подробнее об этой возможности см. в разделе 2.5.2. На некоторых аппаратных платформах поддерживается возможность организации отдельного глобального стека прерываний, используемого всеми обработчиками.
На платформах, не имеющих подобного стека, обработчики дования. В некоторых системах !р1 0 означает низший уровень приоритета, тогда как в иных это значение может оказаться наивысшим. Для облегчения создания процедур обработки прерываний и драйверов устройств в системах ПЫ1Х представлен набор триггеров для блокировки и разблокирования прерываний. Однако в различных реализациях системы для одних и тех же целей используются различные триггеры. В табл.
2.1 показаны некоторые триггеры, применяемые в 4.3В50 и 5'у'тс4. 76 Глава 2. Ядро и процессы Генерация прерывания Сохранение прерывания в специальном регистре петг 1р1» сш 1Р1? Блокировка, пока есть более приоритетные прерывания Да Создание нового уровня контекста; сохранение указателя команд и РЗтУ Разблокирование Восстановление 1р1 и РЗУУ Разблокирование прерывания с наибольшим приоритетом Можно ли разблокировать другое прарываниет Нет Возврат в Рабочий Режим Рис. 2.5.
Алгоритм обработки прерываний 2.5. Синхронизация Ядро системы УХ!Х является реентерабельным. В любой момент времени в ядре могут быть активны сразу несколько процессов. Конечна, на однопроцессорных системах только один из них окажется текущим, в то время как задействуют стек ядра текущего процесса. В таком случае должен быть обеспечен механизм изоляции остальной части стека ядра от обработчика, Для этого ядро помещает в свой стек уровень контекста перед вызовом обработчика. Этот уровень контекста, подобно кадру стека, содержит в себе информацию, необходимую для восстановления контекста выполнения, предществующего вызову обработчика прерывания.
2.5. Синхронизация 77 остальные будут блокированы, находясь в режиме ожидания освобождения процессора или иного системного ресурса. Так как все эти процессы используют одну и ту же копию структур данных ядра, необходимо обеспечивать некоторую форму синхронизации для предотвращения порчи ядра. На рис. 2.6 показан пример, который показывает, к чему может привести отсутствие синхронизации. Представьте, что процесс пытается удалить элемент Б из связанного списка.
После выполнения первой строки кода происходит прерывание, разрешающее другому процессу начать работу. Если второй процесс попытается получить доступ к тому же списку, то обнаружит его в противоречивом состоянии, как это показано на рис. 2.6, б, Становится очевидным, что необходимо использовать некий механизм, защищающий от возникновения подобных проблем. Рис.
2.6. Пример удаления элемента из связанного списка: а — начальное положение; б — после В->отеч->пакт = В->пах); в — восле В->пехь>ргеч = В->ргеч; г — после ггее(В) В системе 1ЛЧ1Х применяется несколько различных технологий синхронизации. Система изначально создана невытесняющей. Это означает, что процесс, выполняющийся в режиме ядра, не может быть вытеснен другим процессом, даже если отведенный виу квант времени ужв исчерпан. Процесс должен самостоятельно освободить процессор. Это обычно происходит в тот момент, когда процесс приостанавливает свою работу в ожидании необходимого ресурса или какого-то события; когда процесс завершил функционирование в режиме ядра и когда собирается возвращаться в режим задачи. В любом случае, так как процесс освобождает процессор добровольно, он может быть уверен, что ядро системы находится в корректном состоянии.
(Современные системы 0Х1Х, работающие в режиме реального времени, поддерживают возможность вытеснения при определенных условиях, см. подробнее раздел 5.6.) Создание ядра системы не вытесняющим является гибким решением большинства проблем, связанных с синхронизацией. Вернемся к примеру, показанному на рис.
2.6. В данном случае ядро системы может обрабатывать связанный 78 Глава 2. Ядро и процессы список без его блокировки, не беспокоясь о возможном вытеснении. Существуют три ситуации, при возникновении которых необходима синхронизация: + операции блокировки; + прерывания; + работа многопроцессорных систем. 2.5.1. Операции блокировки Операция блокировки — это операция, которая блокирует процесс (то есть переводит процесс в спящий режим до тех пор, пока блокировка не будет снята). Так как ядро системы не является вытесняющим, оно может манипулировать большинством объектов (структурами данных и ресурсами) без возможности причинения им какого-либо вреда, так как заранее известно, что никакой другой процесс не может получить к ним в это время доступ. Однако существует некоторое количество объектов, которым необходима защита на время проведения блокировки. Для этого существуют специальные дополнительные механизмы.
Например, процесс может производить операцию ~еаза (чтения) из файла в блочный буфер диска, находящийся в памяти ядра. Так как необходима процедура ввода-вывода с диска, процесс должен ожидать ее завершения, позволив в этот период времени выполняться другому процессу. Однако в этом случае ядру необходимо точно знать, что новый процесс ни в коем случае не получит доступ к буферу, так как тот находится в незавершенном состоянии. Для зашиты таких объектов ядро ассоциирует с ними атрибут зашиты 1ос1.
Он может иметь простейшую реализацию и представлять собою однобитовый флаг, значение которого устанавливается, если объект заблокирован и сбрасывается в противоположном случае. 11еред тем как начать пользоваться каким-либо объектом, каждый процесс обязан проверять, не заблокирован ли требуемый объект.
Если тот свободен, процесс устанавливает флаг блокировки, после чего начинает использование ресурса. Ядро системы также ассоциирует с объектом еще один флаг — вап1ед (необходимость). Флаг устанавливается на объект процессом, если тот ему необходим, но в данный момент времени заблокирован. Когда другой процесс заканчивает использование объекта, то перед его освобождением проверяет флаг яаптед и «будит» те процессы, которые ожидают данный объект, Такой механизм позволяет процессу блокировать ресурс на долгий период времени, даже если процесс приостанавливает свою работу, передавая возможность выполнения другими удерживая при этом необходимый ему ресурс.
На рис. 2.? показан алгоритм блокировки ресурсов. Необходимо учитывать следующие замечания: + процесс блокирует себя в том случае, если не может получить необходимый ресурс,' или в случае ожидания события, например завершения ввода-вывода. Для этого процесс вызывает процедуру з(еерО. Вышеописанный процесс называется блокировкой по событию или ресурсу. 2.5. Синхронизация 79 + Процедура з(еер() помещает процесс в специальную очередь блокированных процессов, изменяет его режим на спящий и вызывает функцию зигтс)т() для инициализации переключения контекста и дальнейшего разрешения выполнения следующего процесса, + Процесс, освобождающий ресурс, вызывает процедуру вга(сеарО для пробуждения всех процессов, ожидающих зтот ресурс'.
Функция ига)гецрО находит все эти процессы, изменяет их режим на работоспособный и помещает их в очередь планировщика, в которой они ожидают выполнения. + Иногда промежуток, прошедший между моментом, когда процесс был разбужен, и временем, когда подошла его очередь выполняться, бывает очень большим. Возможна такая ситуация, что другие текущие процессы могут снова занять необходимый ему ресурс. + Следовательно, после пробуждения процессу необходимо снова проверить, доступен ли необходимый ресурс. Если тот оказывается занятым, то процесс снова переходит в спящий режим. Рис. 2.7.