OSDev http://osdev.su/ |
|
Очередь сообщений http://osdev.su/viewtopic.php?f=5&t=1510 |
Страница 1 из 1 |
Автор: | v.g.a. [ 14 июл 2017, 17:31 ] |
Заголовок сообщения: | Очередь сообщений |
Рассмотрим обычный компьютер. Нажимаются клавиши на клавиатуре, движется мышь и на ней кнопки нажимаются, сетевые пакеты по Ethernet сыпятся. Все эти события вызывают прерывания, обработчики в драйверах отрабатывают, данные попадают в буфер драйвера. Тут возникает вопрос, а дальше что? Думал некоторое время над этим вопросом. Проблема в том, что устройств много, а все события должны обрабатываться последовательно, иначе невозможно. Вариант 1. У каждого драйвера есть своя очередь событий, учитывающая специфику устройства (у клавиатуры скан-код 1 байт, у мыши пакет 3-4 байта, у сетевой карты размер пакета побольше). Каждому событию присваиваем уникальный код, увеличивающийся во времени. Менеджер ввода-вывода опрашивает буферы, забирает из них данные и отправляет на обработку. Все синхронизировано по этому уникальному коду. Вариант 2. Есть общая очередь событий. Размер данных в этой очереди может быть произвольным. Обработчик прерывания помещает в эту очередь событие. Уникальный код не нужен. Менеджер ввода-вывода извлекает из очереди событие (данные) и отправляет на обработку. В очереди для события нужно хранить и тип, и размер. В общем склоняюсь ко второму варианту. Но и у первого есть преимушество, в плане работы с аппаратурой, там DMA и т.д. У кого какие мнения? Может есть третий вариант? |
Автор: | v.g.a. [ 14 июл 2017, 17:46 ] |
Заголовок сообщения: | Re: Очередь сообщений |
Почему вопрос появился, драйвер контроллера клавиатуры ps/2 работает, но уже есть два устройства - клавиатура и мышь. Два обработчика прерываний помещают данные в свои буферы. Нужно реализовывать интерфейс драйверов. Иначе потом придётся переписывать код. Нужно что-то похожее на очереди сообщений (IPC). Будет такая цепочка: Драйвер контроллера ps/2 -- Драйвер клавиатуры (Драйвер мыши) -- Менеджер ввода/вывода -- Менеджер оконного интерфейса? Дальше с железом желания нет возиться. Нужно чтобы работало хорошо то, что есть. |
Автор: | pavia [ 17 июл 2017, 08:57 ] |
Заголовок сообщения: | Re: Очередь сообщений |
Я даже близко к этому не приблизился. Давай как в той песни . Всё хорошо прекрасная Маркиза и хороши у нас дела. Цитата: Проблема в том, что устройств много, а все события должны обрабатываться последовательно, иначе невозможно Ну по чему же не возможно? События можно обрабатывать последовательно, параллельно и асинхронно. Цитата: Обработчик прерывания помещает в эту очередь событие. А как же безопасность? Мы же должны заблокировать очередь на запись. А как вы планируете это сделать если мы в обработчике прерывания(другие прерывания заблокированы)? Цитата: У каждого драйвера есть своя очередь событий, учитывающая специфику устройства (у клавиатуры скан-код 1 байт, у мыши пакет 3-4 байта, у сетевой карты размер пакета побольше). А что мешает данные напрямую отдавать приложению? Тем более если писать их в очередь то это снижает эффективность DMA.Приложение вызвало ReadData - функция эта блокирующая. Т.е она будет жать и не отдавать управление приложению до тех пор пока данные не окажутся в буфере. Следовательно драйвер уже знает адрес буфера и может туда начинать писать. Прерывание придёт когда данные будут записаны. Для устройств без DMA, эмитируем это поведение прямо в обработчике прерывания. Тем более у них данные по 1-16 байт. А вот после обработчик прерывания может писать в очередь сообщений 1 бит с указанием флага. Цитата: Может есть третий вариант? Конечно, если у вас ОС жёсткого реального времени (ОСЖРВ). То можно без очередей. А если просто РВ, то такие очереди можно перенести из ядра в прикладные приложения. |
Автор: | v.g.a. [ 17 июл 2017, 21:47 ] |
Заголовок сообщения: | Re: Очередь сообщений |
Цитата: А что мешает данные напрямую отдавать приложению? Тем более если писать их в очередь то это снижает эффективность DMA. Приложение вызвало ReadData - функция эта блокирующая. Т.е она будет жать и не отдавать управление приложению до тех пор пока данные не окажутся в буфере. Следовательно драйвер уже знает адрес буфера и может туда начинать писать. Прерывание придёт когда данные будут записаны. Для устройств без DMA, эмитируем это поведение прямо в обработчике прерывания. Тем более у них данные по 1-16 байт. А вот после обработчик прерывания может писать в очередь сообщений 1 бит с указанием флага. Приложение может не успевать обрабатывать данные, пусть временно. И обработчику прерывания нужно данные из аппаратуры куда-то записывать. |
Автор: | v.g.a. [ 17 июл 2017, 21:57 ] |
Заголовок сообщения: | Re: Очередь сообщений |
Цитата: А как же безопасность? Мы же должны заблокировать очередь на запись. А как вы планируете это сделать если мы в обработчике прерывания(другие прерывания заблокированы)? Что то я про прерывания не понял до конца. А очередь надо блокировать конечно. Имеете ввиду что приложение извлекает данные из очереди, а тут возникает прерывание? И целостность очереди нарушена? |
Автор: | pavia [ 18 июл 2017, 06:07 ] |
Заголовок сообщения: | Re: Очередь сообщений |
v.g.a. писал(а): Что то я про прерывания не понял до конца. А очередь надо блокировать конечно.Имеете ввиду что приложение извлекает данные из очереди, а тут возникает прерывание? И целостность очереди нарушена? Да. Так и есть. В прерывание вы не можете ждать пока спин-блокировка снимется. Цитата: Приложение может не успевать обрабатывать данные, пусть временно. И обработчику прерывания нужно данные из аппаратуры куда-то записывать. Если приложение не успевает то это его проблема. Произошло прерывание внутри IRQ данные вычитываются из контролёра 8042. Помещаются в буфер. Взводиться флаг прерывания. И выходим из обработчика прерывания. Далее возможно два татарина параллельный вызов и асинхронный вызов. При параллельном мы сразу попадаем в обработчик прерывания. При асинхронным на ближайшем цикле проверке асинхронных вызовов проверяете флаги от всех прерываний и если оно появилось, то вызываем обработчик прерывания. Собственно у таких обработчиков высший приоритет. В таком под ходе вам ничего не мешает дождаться освобождения спин блокировке вашей очереди. Очередь как по мне ненужна. Но раз хотите так почему бы и нет. APC вызываются каждый раз как какое приложение задумает обратиться к ОС или по прерыванию таймера вызывать системный процесс который будет дёргать APC. Поэтому периоды между APC составляют 1-100 мкс. А прерывания приходят в периоды 100 мкс- 1 с. И частота их соответственно у прерываний 100-30 000 у APC их порядка 1-1000 раз выше. Правда надо подумать что будет если у вас будет 0 или 1 приложение. Если 0 ппиложений, то нестрашно что мы потеряем прерывания. Третий вариант. В обработчике прерывания данные невычитываем. Выставляем флаг прерывания и переходим в процесс обработки прерываний. Там переодически опрашиваются флаги и вызывается нужный обработчик. Он уже вычитывает даные и передаёт их в очередь. Пожалуй лучший вариант. Только надо сделать процессы с приоритетами. В отдельном процессе вы можете дождаться пока блокировка снимется. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |