c57a7841

Структуры данных


В этом разделе рассматриваются наиболее важные структуры данных, используемые в коде обработки сигналов.


Просмотрев несколько из них, читатель получит представление о всех. Этот фрагмент был выбран, как читатели вероятно догадались, из раздела файла, содержащего идентификаторы устройств для РСI-видеоплат на основе чипов S3.

Хотя dev_id является указателем, он ни на что не указывает и попытка раскрыть его была бы ошибкой. Значение имеет только его разрядный шаблон.

  • next — указатель на следующую структуру struct irqaction в очереди, если IRQ используется совместно. Обычно IRQ не является используемым совместно, и, следовательно, значение этого члена равно NULL.


  • Следующие две представляющие интерес структуры данных находятся в архитектурно-зависимом файле arch/i386/kernel/irq.h. Первая структура struct hw_interrupt_type (строка ) аннотирует контроллер прерываний. В основном, она представляет собой набор указателей на функции, которые выполняют характерные для контроллера операции:

  • typename — читабельное имя контроллера.


  • startup — разрешает в этом контроллере события данного IRQ.


  • shutdown — запрещает в этом контроллере события данного IRQ.


  • handle — обрабатывает отдельное прерывание в IRQ, переданного функции.


  • enable и disable — в основном аналогичны startup и shutdown; существующие различия не имеют значения ни для одного из кодов, анализируемых в этой книге. (Фактически, функции enable/disable и startup/shutdown идентичны для всех приведенных в книге кодов.)


  • Вторая, представляющая интерес структура данных этого файла, irq_desc_t (строка ), имеет следующие члены:

  • status — целое значение, разряды которого для ноля или более флагов получены из набора, определенного в строках с по . Вместе они представляют состояние IRQ — отключен ли IRQ, являются ли в настоящий момент связанные с IRQ устройства автоматически определяемыми и т.п.


  • handler — указатель на структуру struct hw_interrupt_type.


  • action — указывает на начало очереди структур struct irqaction. Обычно, как отмечалось ранее, для каждого IRQ существует только одно действие, поэтому связанный список имеет длину равную 1 (или 0). Но, если IRQ используется совместно двумя или более устройствами, в очереди будет соответствующее количество действий.




  • depth — количество текущих пользователей этой структуры irq_desc_t. В основном этот член используется, чтобы убедиться в том, что IRQ не отключен, пока событие обслуживается.


  • Структуры irq_desc_t организуются в массив irq_desc (строка ). Для каждого IRQ существует одна запись массива, и таким образом массив сопоставляет номер каждого IRQ соответствующему обработчику и другой информации в структуре irq_desc_t.

    Последний заслуживающий упоминания набор структур данных начинается в строке ; эти структуры связанны с нижними половинами:

  • bh_mask_count (строка ) — массив, который отслеживает вложенные пары запросов включения/отключения для каждой нижней половины. Эти запросы выполняются посредством вызова функций enable_bh (строка ) и disable_bh (строка ), Каждый запрос на отключение увеличивает значение счетчика; каждый запрос на включение уменьшает его. Если значение счетчика достигает 0, значит все непогашенные отключения были замещены включением, и, следовательно, нижняя половина наконец снова включена.


  • bh_mask и bh_active (строки и A HREF="part1_39.htm#l14857">14857) — вместе эти члены управляют тем, будет ли выполнена нижняя половина. Каждый из них имеет 32 разряда, по одному разряду на нижнюю половину. Когда верхняя половина (или какая-либо другая часть кода) решает, что его нижняя половина должна быть выполнена, она помечает ее, устанавливая разряд в bh_active (используя mark_bh, строка ). Независимо от того, была ли она помечена таким образом, нижняя половина может быть полностью отключена посредством очистки соответствующего разряда в bh_mask — enable_bh и disable_bh делают это, одновременно настраивая запись bh_mask_count.

    Следовательно, поразрядное AND членов bh_mask и bh_active определяет, какие нижние половины должны быть выполнены. В частности, если результатом поразрядаого AND является 0, никакие нижние половины не должны быть выполнены. Эта технология используется в ядре неоднократно, как, например, в макросе get_active_bhs (строка ).

  • bh_base (строка ) — это просто массив указателей на функции нижней половины.


  • Неименованная структура enum — неименованная структура enum, начинающаяся в строке , связывает символическое имя с каждой из используемых ядром нижних половин. Например, чтобы пометить в качестве активной нижнюю половину таймера, нужно было бы написать:

    mark_bh (TIMER_BH);

    Строка именно это и делает.


    Содержание раздела