Асинхронне уведення-виведення
У системах сімейства Unix драйвери блокових пристроїв обов'язково асинхронні.
Крім того, в сучасних версіях системи асинхронними драйверами є
драйвери потокових пристроїв. Багато інших ОС, у тому числі однозадачні
(такі, як DEC RT-11), використовують виключно асинхронні драйвери.
Драйвер,
що використовує асинхронну архітектуру, зазвичай надає замість
окремих функцій read, write, ioctl і так далі
єдину функцію, яка в системах сімейства Unix називається strategy
а ми називатимемо стратегічною функцією
(мал. 10.7).
Запити до драйвера в VMS
У операційній системі VAX/VMS драйвер отримує запити на уведення-виведення
з черги запитів. Елемент черги називається IRP (lnput[Output] Request
Packet — пакет запиту введення-виводу). Обробивши перший запит в черзі,
драйвер починає обробку наступного. Операції над чергою запитів
виконуються спеціальними командами процесора VAX і є атомарними.
Якщо черга порожня, основна нитка драйвера завершується. При появі
нових запитів система знов запустить її.
Мал. 10.7. Стратегічна функція і черга запитів
IRP містить:
- код операції (читання, запис або
код SPFUN— спеціальна функція, подібна ioctl в системах сімейства Unix);
- адреса блоку даних, які мають бути
записані, або буфера, куди дані необхідно помістити;
- інформацію, використовувану при обробці поста, зокрема, ідентифікатор
процесу, що запитав операцію.
Залежно від коди операції драйвер запускає відповідну підпрограму.
У VAX/VMS адреса підпрограми вибирається з таблиці FDT (Function Definition
Table). Підпрограма ініціює операцію і припиняє процес,
даючи системі можливість виконати інші активні процеси. Потім,
коли відбувається переривання, його обробник ініціює fork-процесс, виконуючий
наступні етапи цього запиту. Завершивши один запит, fork-процесс повідомляє
про це процедури обробки (розбудивши відповідний процес) поста
і, якщо в черзі ще щось залишилося, починає виконання наступного
запиту.
Як параметр стратегічна функція отримує покажчик на структуру
запиту, в якій містяться код необхідної операції і блок даних. При
цьому виникає складне питання, а саме — в якому адресному просторі
розміщується цей блок?
На перший погляд,
ідеальним рішенням
було б розміщення цього блоку відразу в призначеному для користувача адресному
просторі. Проблема тут в тому, що стратегічна функція — особливо
при обробці не першого запиту в черзі — виконується не в призначеному
для користувача контексті, коли можна застосовувати примітиви обміну даними
з адресним простором завдання, в контексті fork-процесу,
а то і в контексті переривання, коли адресний простір користувача
не визначений.
Можливі два варіанти вирішення
цієї проблеми: зберігати в структурі запиту ченці і покажчик на
призначений для користувача адресний простір, або все-таки копіювати дані
в адресний простір системи на етапі передобробки, і назад
в призначене для користувача на етапі постобробки запиту. Драйвер в
цьому випадку не повинен турбуватися ні про яке копіювання, зате розробник
ОС отримує додатковий головний біль у вигляді логіки управління буферами
в адресному просторі системи і виділення пам'яті для них.
Буферизація запитів і формування черги до блокових пристроїв в Unix
здійснюється спеціальним модулем системи, який називається дисковим
кешем . Принцип роботи дискового кеша обговорюватиметься в разд.
Дисковий кеш. Черги запитів до потокових пристроїв
мають менший об'єм, тому виділення пам'яті для них здійснюється звичайним
kmalloc. |