- •26. Синхронизация
- •27. Оповещения и асинхронные вызовы процедур
- •28. Структура процессов
- •Требования подсистем среды
- •29. Базовая структура процессов
- •Управление клиентскими процессами
- •Как предотвратить неправильное использование
- •52. База данных страничных фреймов
- •53. Дескрипторы виртуальных адресов
- •Соображения мультипроцессорной обработки
- •Соображения переносимости
- •Общие сведения
- •Планирование потоков
- •55. Объекты процесс ядра и поток ядра
- •56. Приоритеты планирования
- •Переключение контекста
- •57. Обработка прерываний и исключений
- •Обработчик ловушки
- •Распределение прерываний
- •58. Таблица распределения прерываний. Программные прерывания. Прерывания асинхронного вызова процедур (apc).
- •Прерывания асинхронного вызова процедуры (арс)
- •59. Распределение исключений
- •60. Многопроцессорная синхронизация
- •Синхронизация на уровне ядра
- •61. Синхронизация на уровне исполнительной системы
- •Восстановление после сбоя питания
Соображения мультипроцессорной обработки
Любой код, который может выполняться одновременно на нескольких процессорах, должен удовлетворять некоторым ограничениям. Он должен быть реентерабельным, предотвращать одновременное использование несколькими потоками глобальных структур данных и не позволять двум потокам захватывать ресурсы таким образом, чтобы заблокировать друг друга (взаимоблокировка, или клинч, deadlock). Кроме того, на многопроцессорных системах существуют специфические проблемы производительности (отсутствующие на однопроцессорных машинах).
Диспетчер виртуальной памяти реентерабелен, так что для него основными проблемами были предотвращение разрушения данных и взаимоблокировок, а также достижение хорошей производительности.
Для защиты своей самой важной структуры данных — базы данных страничных фреймов — диспетчер виртуальной памяти использует спин-блокировку. Всякий раз, когда возникает страничная ошибка, средство подкачки страниц перехватывает управление вызвавшим ее потоком, обрабатывает ошибку и обновляет базу данных. Прежде чем получить доступ к базе данных, поток должен завладеть связанной с нею спин-блокировкой. Пока поток владеет спин-блокировкой, никакой другой поток не может читать или записывать в базу данных страничных фреймов. Таким образом, когда в Windows NT происходят две страничных ошибки одновременно, один из потоков приостанавливается до освобождения базы данных страничных фреймов.
Задержка доступа потока к базе данных страничных фреймов является примером противоречия между скоростью выполнения и требованиями многопроцессорной системы. Диспетчер виртуальной памяти мог бы позволить нескольким потокам одновременно обращаться к разным частям базы данных, разбив ее на несколько структур данных и защитив каждую часть отдельной блокировкой. Однако получение и освобождение блокировки — дорогостоящая операция, поэтому обработка страничных ошибок выполнялась бы дольше, если бы потоку пришлось захватывать три блокировки вместо одной. Разработчики отдали предпочтение скорости обработки страничных ошибок перед большей степенью параллелизма средства подкачки страниц. Они решили использовать для защиты базы данных одну блокировку, предполагая, что при меньших накладных расходах поток будет быстрее входить и выходить из владения базой данных, освобождая ее для других потоков.
Использование одной блокировки означает, что база данных страничных фреймов может стать узким местом при интенсивной подкачке страниц. Чтобы избежать этого, диспетчер виртуальной памяти пытается минимизировать количество страничных ошибок. Для этого он делает следующее:
•предоставляет каждому процессу достаточное количество страниц в рабочем наборе;
•автоматически урезает рабочие наборы процессов, чтобы излишние или неиспользуемые страницы стали доступны другим процессам.
Соображения переносимости
Диспетчер виртуальной памяти зависит от определенных аппаратных возможностей. Ниже приведены требования, которые он предъявляет к процессору:
• 32-разрядные адреса (64-разрядные адреса поддерживаются, но требуют некоторой переделки диспетчера виртуальной памяти).
• Поддержка виртуальной памяти и подкачки страниц. Процессор должен предоставлять возможность отображения виртуальных адресов в физические, а также предоставлять механизмы подкачки.
• Прозрачные, когерентные аппаратные кэши на многопроцессорных системах. Когда поток, исполняющийся на одном из процессоров, обновляет данные в кэше последнего, все другие процессоры должны получить уведомление, что их кэши теперь содержат некорректные данные.
• Совмещение виртуальных адресов. Процессор должен допускать отображение на один и тот же страничный фрейм двух элементов таблицы страниц одного и того же процесса. ОС часто использует страницу совместно с пользовательским процессом, отображая второй элемент таблицы страниц.
Некоторые части диспетчера виртуальной памяти зависят от особенностей процессора, на котором исполняется ОС. Перечисленные ниже части диспетчера памяти должны быть модифицированы для каждой аппаратной платформы, на которую он переносится.
• Элементы таблицы страниц. Когда элемент таблицы страниц действителен, процессор подразделяет эти 32 бита на поля и устанавливает их значения соответствующим образом. Когда элемент недействителен, диспетчер виртуальной памяти использует остальной 31 бит по своему усмотрению. Формат, выбираемый им, зависит от средств виртуальной памяти, предоставляемых процессором.
• Размер страницы. Разные процессоры используют разные размеры страницы. Диспетчер виртуальной памяти выделяет ее в пределах блока в 64 Кбайт, что гарантирует возможность поддержки любого размера страницы от 4 до 64 Кбайт. Страницы менее 4 Кбайт не поддерживаются.
• Защита страниц. Способ использования диспетчером виртуальной памяти аппаратной защиты страниц для реализации дополнительной программной защиты, естественно, аппаратно зависим.
• Трансляция виртуального адреса. Алгоритм, используемый диспетчером виртуальной памяти для трансляции виртуального адреса в номер элемента таблицы страниц, тоже аппаратно зависим.
54. Операционная система, как и любая большая программная система, состоит из расположенных друг над другом уровней кода. Верхние уровни используют более примитивные (но в данном случае более мощные) функции и структуры данных нижних уровней.
Ядро выполняет наиболее фундаментальные функции Windows NT, определяя, как ОС использует процессор или процессоры и обеспечивая рациональность их использования. Таким образом, эффективность всей ОС зависит от правильной и эффективной работы ядра.
Главной задачей разработчиков при создании ядра NT было обеспечение базы, состоящей из примитивов и механизмов с тщательно определенным и предсказуемым поведением, которые позволили бы высокоуровневым компонентам исполнительной системы NT выполнять свои задачи. Используя примитивы ядра, исполнительная система NT может создавать бесконечное разнообразие абстракций высокого уровня. Ей не нужно использовать для этого недокументированные интерфейсы и хитрые трюки или непосредственно обращаться к аппаратуре. Ядро отделяет себя от остальных частей исполнительной системе, реализуя механизмы ОС и избегая установления жестких правил.
Предоставляя богатый набор контролируемых универсальных механизмов, ядро NT позволяет Windows NT расти и расширяться предсказуемым и упорядоченным образом. (Для простоты будем использовать термин исполнительная система (executive) для обозначения всех компонентов ОС, работающих в режиме ядра, за исключением самого ядра.)
