Буферизация
побайтная передача данных между драйвером сигнального устройства и прикладным процессом весьма неэффективна.
При таком режиме работы байт должен быть сначала скопирован в адресное пространство драйвера, затем некоторое время должно пройти, прежде чем драйвер сможет передать этот символ физическому устройству. Если при этом устройство оказывается занятым, процесс должен ожидать завершения предыдущей операции, что, скорее всего, вынудит его перейти в сосостояние сна и приведет к переключению контекста.
Существует несколько способов преодолеть данную ситуацию, но все они предполагают обеспечение некоторой буферизации данных драйвером устройства.
Первый способ заключается в использовании прерываний, когда при постотуплении на устройство следующего символа, генерируется аппаратное прерывание, которое обрабатывается функцией xxintr () драйвера не-
зависимо от функции xxwrite (). Функция обработки прерывания записывает данные в буфер, которые затем считываются функцией xxwrite ().
Если устройство не поддерживает прерываний, их поступление можно сэмулировать с помощью функции xxpoll () драйвера устройства, которая вызызывается ядром через определенные промежутки времени (обычно каждый сигнал таймера). Обычно функция xxpoll (), в свою очередь, вызывает функцию xxintr (), скажем, на каждый десятый сигнал таймера, обеспечивая тем самым независимое считывание и буферизацию данных.
Буферизация данных для символьных устройств осуществляется с помощью специальных структур данных, называемых clist. Каждая структура clist имеет следующие поля:
int с_сс
struct cblcck *c_cf
struct cblock *c_cl
c_cc содержит число символов в буфере cblock.
c_cf и c_cl указывают, соответственно, на первый и последний элементы cblock,
организованные в виде связанного списка и фактически обеспечивающие буферы хранения данных.
Каждая структура cblock может хранить несколько символов. Когда буфер хранения заполняется, ядро автоматически выделяет новую структуру cblock и помещает ее в связанный список. Поля структуры cblock и их использование приведены на рис. 5.9.
- Подсистема ввода/вывода
- Драйверы устройств
- Типы драйверов
- Базовая архитектура драйверов
- Файловый интерфейс
- Vnode а также inode физической файловой системы, где расположен специальный файл устройства, и соответствующий ему vnode.
- Встраивание драйверов в ядро
- Блочные устройства
- Символьные устройства
- Интерфейс доступа низкого уровня
- Буферизация
- Архитектура терминального доступа
- Псевдотерминалы