Стратегии буферизации для символьных устройств
По традиции Unix-подобные операционные системы делят аппаратные устройства на блочные и символьные. Однако такая классификация не дает полной картины. Некоторые устройства способны передавать большие объемы данных за одну операцию ввода/вывода, в то время как другие передают лишь несколько символов.
Например, драйвер мыши PS/2 за каждую операцию чтения получает несколько байтов, в которых содержится информация о состоянии кнопки мыши и о позиции указателя мыши на экране. Таким устройством управлять проще всего. Вначале входные данные посимвольно считываются с входного регистра и сохраняются в соответствующей структуре ядра. Затем эти данные в подходящий момент времени копируются в адресное пространство процесса.
Аналогичным образом, выходные данные вначале копируются из адресного пространства процесса в соответствующую структуру ядра, а затем посимвольно копируются в выходной регистр устройства ввода/вывода. Очевидно, что драйверы ввода/вывода для таких устройств не пользуются механизмом DMA, поскольку процессорное время, затраченное на настройку операций ввода/вывода с прямым доступом к памяти, сравнимо со временем, необходимым для пересылки данных на порты ввода/вывода или обратно.
С другой стороны, ядро должно быть также готово к работе с устройствами, перемещающими большое количество байтов за каждую операцию вво
да/вывода. Это могут быть либо последовательные устройства, такие как звуковые или сетевые карты, либо устройства с произвольным доступом, например, все виды дисковых приводов (гибкие, CD-ROM, SCSI и т. д.).
Предположим, вы настроили звуковую карту на компьютере так, что можете записывать звуки с помощью микрофона. Звуковая карта оцифровывает электрический сигнал, поступающий с микрофона, с фиксированной частотой, скажем, 44,14 кГц. В результате она выдает поток 16-битовых чисел, разделенный на блоки входных данных. Драйвер звуковой карты должен уметь справляться с такой лавиной информации в любой ситуации, даже когда центральный процессор занят выполнением другого процесса.
Этого можно добиться, сочетая две разные методики:
- использование для передачи блоков данных механизма DMA;
- использование циклического буфера из двух и более элементов, каждый из которых имеет размер, равный блоку данных. Когда возникнет прерывание, сигнализирующее, что прочитан новый блок данных, обработчик прерывания передвинет указатель на элемент циклического буфера так, чтобы следующие данные записывались в пустой элемент. И наоборот, как только драйвер успешно скопирует блок данных в адресное пространство пользователя, он освобождает элемент циклического буфера, чтобы он был доступен для сохранения новых данных от аппаратного устройства.
Задача циклического буфера заключается в сглаживании пиков загрузки центрального процессора. Даже если приложение режима пользователя, принимающее данные, замедлит свою работу из-за наличия более приоритетных задач, схема DMA сможет продолжать заполнять элементы циклического буфера, потому что обработчик прерываний работает за счет текущего процесса.
Сходная ситуация возникает при приеме пакетов от сетевой карты, но в этом случае поток поступающих данных является асинхронным. Пакеты принимаются независимо друг от друга, и временной интервал между приходом двух пакетов непредсказуем.
Учитывая все сказанное, работа с буфером для последовательных устройств не представляет трудности, поскольку один и тот же буфер никогда не используется повторно. В самом деле, не может же аудиоприложение попросить микрофон снова передать предыдущий блок данных.
Мы увидим в главе 75, что буферизация для устройства с произвольным доступом (все виды дисковых накопителей) является гораздо более сложной задачей.
Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница