на главную | войти | регистрация | DMCA | контакты | справка | donate |      

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я


моя полка | жанры | рекомендуем | рейтинг книг | рейтинг авторов | впечатления | новое | форум | сборники | читалки | авторам | добавить




Синхронизация

Драйверы должны синхронизировать свое обращение к глобальным данным и регистрам устройств в силу двух причин.

Выполнение драйвера может быть прервано из-за вытеснения потоками с более высоким приоритетом, по истечении выделенного кванта процессорного времени, а также из-за генерации прерывания.

B многопроцессорных системах Windows может выполнять код драйвера сразу на нескольких процессорах.


Без синхронизации данные могут быть повреждены. Например, код драйвера устройства выполняется при IRQL уровня «passive». Какая-то программа инициирует операцию ввода-вывода, в результате чего возникает аппаратное прерывание. Оно прерывает выполнение кода драйвера и активизирует его ISR. Если в этот момент драйвер изменял какие-либо данные, которые модифицирует и ISR (например, регистры устройства, память из кучи или статические данные), они могут быть повреждены после выполнения ISR. Эту проблему демонстрирует рис. 9-15.

3.Внутреннее устройство Windows (гл. 8-11)

Bo избежание такой ситуации драйвер, написанный для Windows, должен синхронизировать обращение к любым данным, которые он разделяет со своей ISR Прежде чем обновлять общие данные, драйвер должен заблокировать все остальные потоки (или процессоры, если система многопроцессорная), чтобы запретить им доступ к тем же данным.

Ядро Windows предоставляет специальную синхронизирующую процедуру KeSynchronizeExecution, которую драйверы устройств должны вызывать при доступе к данным, разделяемым с ISR. Эта процедура не допускает выполнения ISR, пока драйвер обращается к общим данным. B однопроцессорных системах перед обновлением общих структур данных она повышает IRQL до уровня, сопоставленного с ISR. Ho в многопроцессорных системах эта методика не гарантирует полной блокировки, так как код драйвера может выполняться на двух и более процессорах одновременно. Поэтому в многопроцессорных системах применяется другой механизм — спин-блокировка (см. раздел «Синхронизация ядра» главы 3). Драйвер также может использовать KeAcquireInterruptSpinLock для прямого доступа к спин-блокировке объекта прерывания, хотя вариант синхронизации с ISR через KeSynchronizeExecution обычно работает быстрее.

Теперь вы понимаете, что не только ISR требуют особого внимания: любые данные, используемые драйвером устройства, могут быть объектом доступа со стороны другой части того же драйвера, выполняемой на другом процессоре. Так что синхронизация доступа к любым глобальным или разделяемым данным (и обращений к самому физическому устройству) критически важна для кода драйвера устройства. Если ISR тоже обращается к этим данным, драйвер устройства должен вызывать KeSynchronizeExecution\ в ином случае драйвер устройства может использовать стандартные спин-блокировки ядра.



Завершение обработки запроса на ввод-вывод | 3.Внутреннее устройство Windows (гл. 8-11) | Запрос ввода-вывода к многоуровневому драйверу