Реализация тасклетов
Реализация тасклетов
Так как тасклеты реализованы на основе отложенных прерываний, они тоже являются отложенными прерываниями (softirq). Как уже рассказывалось, тасклеты представлены двумя типами отложенных прерываний: HI_SOFTIRQ и TASKLET_SOFTIRQ. Единственная разница между ними в том, что тасклеты типа HI_SOFTIRQ выполняются всегда раньше тасклетов типа TASKLET_SOFTIRQ.
Структуры тасклетов
Тасклеты представлены с помощью структуры tasklet_struct. Каждый экземпляр структуры представляет собой уникальный тасклет. Эта структура определена в заголовочном файле <linux/interrupt.h> в следующем виде.
struct tasklet_struct {
struct tasklet_struct *next; /* указатель на следующий
тасклет в списке */
unsigned long state; /* состояние тасклета */
atomic_t count; /* счетчик ссылок */
void (*func)(unsigned long); /* функция-обработчик тасклета */
unsigned long data; /* аргумент функции-обработчика тасклета */
);
Поле func — это функция-обработчик тасклета (эквивалент поля action для структуры, представляющей отложенное прерывание), которая получает поле data в качестве единственного аргумента при вызове.
Поле state может принимать одно из следующих значений: нуль, TASKLET_STATE_SCHED или TASLET_STATE_RUN. Значение TASKLET_STATE_SCHED указывает на то, что тасклет запланирован на выполнение, а значение TASLET_STATE_RUN — что тасклет выполняется. Для оптимизации значение TASLET_STATE_RUN может использоваться только на многопроцессорной машине, так как на однопроцессорной машине и без этого точно известно, выполняется ли тасклет (действительно, ведь код, который выполняется, либо принадлежит тасклету, либо нет).
Поле count используется как счетчик ссылок на тасклет. Если это значение не равно нулю, то тасклет запрещен и не может выполняться; если оно равно нулю, то тасклет разрешен и может выполняться в случае, когда он помечен как ожидающий выполнения.
Планирование тасклетов на выполнение
Запланированные (scheduled) на выполнение тасклеты (эквивалент сгенерированных отложенных прерываний)[39] хранятся в двух структурах, определенных для каждого процессора: структуре tasklet_vec (для обычных тасклетов) и структуре tasklet_hi_vec (для высокоприоритетных тасклетов). Каждая из этих структур — это связанный список структур tasklet_struct. Каждый экземпляр структуры tasklet_struct представляет собой отдельный тасклет.
Тасклеты могут быть запланированы на выполнение с помощью функций tasklet_schedule() и tasklet_hi_schedule(), которые принимают единственный аргумент— указатель на структуру тасклета— tasklet_struct. Эти функции очень похожи (отличие состоит в том, что одна использует отложенное прерывание с номером TASKLET_SOFTIRQ, а другая — с номером HI_SOFTIRQ). К написанию и использованию тасклетов мы вернемся в следующем разделе. А сейчас рассмотрим детали реализации функции tasklet_hi_schedule(), которые состоят в следующем.
• Проверяется, не установлено ли поле state в значение TASKLET_STATE_SCHED. Если установлено, то тасклет уже запланирован на выполнение и функция может возвратить управление.
• Сохраняется состояние системы прерываний и запрещаются прерывания на локальном процессоре. Это гарантирует, что ничто на данном процессоре не будет мешать выполнению этого кода.
• Добавляется тасклет, который планируется на выполнение, в начало связанного списка структуры tasklet_vec или tasklet_hi_vec, которые уникальны для каждого процессора в системе.
• Генерируется отложенное прерывание с номером TASKLET_SOFTIRQ или HI_SOFTIRQ, чтобы в ближайшее время данный тасклет выполнился при вызове функции do_softirq().
• Устанавливается состояние системы прерываний в первоначальное значение и возвращается управление.
При первой же удобной возможности функция do_softirq() выполнится, как это обсуждалось в предыдущем разделе. Поскольку большинство тасклетов помечаются как готовые к выполнению в обработчиках прерываний, то, скорее всего, функция do_softirq() вызывается сразу же, как только возвратится последний обработчик прерывания. Так как отложенные прерывания с номерами TASKLET_SOFTIRQ или HI_SOFTIRQ к этому моменту уже сгенерированы, то функция do_softirq() выполняет соответствующие обработчики. Эти обработчики, а также функции tasklet_action() и tasklet_hi_action() являются сердцем механизма обработки тасклетов- Давайте рассмотрим, что они делают.
• Запрещаются прерывания, и получается весь список tasklet_vec или tasklet_hi_vec для текущего процессора.
• Список текущего процессора очищается путем присваивания значения нуль указателю на него.
• Разрешаются прерывания (нет необходимости восстанавливать состояние системы прерываний в первоначальное значение, так как этот код может выполняться только в обработчике отложенного прерывания, который вызывается только при разрешенных прерываниях).
• Организовывается цикл по всем тасклетам в полученном списке.
• Если данная машина является многопроцессорной, то нужно проверить не выполняется ли текущий тасклет на другом процессоре, то есть проверить не установлен ли флаг TASLET_STATE_RUN. Если тасклет уже выполняется, то его необходимо пропустить и перейти к следующему тасклету в списке (вспомним, что только один тасклет данного типа может выполняться в любой момент времени).
• Если тасклет не выполняется, то нужно установить флаг TASLET_STATE_RUN, чтобы другой процессор не мог выполнить этот тасклет.
• Проверяется значение поля count на равенство нулю, чтобы убедиться, что тасклет не запрещен. Если тасклет запрещен (поле count не равно нулю), то нужно перейти к следующему тасклету, который ожидает на выполнение.
• Теперь можно быть уверенным, что тасклет нигде не выполняется, нигде не будет выполняться (так как он помечен как выполняющийся на данном процессоре) и что значение поля count равно нулю. Необходимо выполнить обработчик тасклета. После того как тасклет выполнился, следует очистить флаг TASLET_STATE_RUN и поле state.
• Повторить описанный алгоритм для следующего тасклета, пока не останется ни одного тасклета, ожидающего выполнения.
Реализация тасклетов проста, но в то же время очень остроумна. Как видно, все тасклеты реализованы на базе двух отложенных прерываний TASKLET_SOFTIRQ и HI_SOFTIRQ. Когда тасклет запланирован на выполнение, ядро генерирует одно из этих двух отложенных прерываний. Отложенные прерывания, в свою очередь, обрабатываются специальными функциями, которые выполняют все запланированные на выполнение тасклеты. Эти специальные функции гарантируют, что только один тасклет данного типа выполняется в любой момент времени (но тасклеты разных типов могут выполняться одновременно). Вся эта сложность спрятана за простым и ясным интерфейсом.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Использование тасклетов
Использование тасклетов В большинстве случаев тасклеты — это самый предпочтительный механизм, с помощью которого следует реализовать обработчики нижних половин для обычных аппаратных устройств. Тасклеты можно создавать динамически, их просто использовать, и они
Реализация TCP/IP
Реализация TCP/IP Прежде чем перейти к описанию функционирования модулей протоколов TCP/IP, рассмотрим еще одну структуру данных, называемую управляющим блоком протокола (Protocol Control Block, PCB), который в случае TCP/IP называется Internet PCB, и представлен структурой inpcb, определенной в
Реализация 4.4BSD
Реализация 4.4BSD Если вы никогда ранее не сталкивались с таким типом устройства сервера (несколько процессов, вызывающих функцию accept на одном и том же прослушиваемом сокете), вас, вероятно, удивляет, что это вообще может работать. Пожалуй, здесь уместен краткий экскурс,
12.3.2 Реализация семафоров
12.3.2 Реализация семафоров Дийкстра [Dijkstra 65] показал, что семафоры можно реализовать без использования специальных машинных инструкций. На Рисунке 12.6 представлены реализующие семафоры функции, написанные на языке Си. Функция Pprim блокирует семафор по результатам проверки
Урок № 84. Реализация НМА
Урок № 84. Реализация НМА Нематериальные активы, как и любые другие активы, могут быть реализованы на сторону. Для отражения в учете операций по реализации нематериальных активов в программе "1С:Бухгалтерия 8" предназначен документ "Передача НМА", с которым мы познакомимся
Глава 5 Реализация
Глава 5 Реализация В основном разработка программы сводится к написанию определений классов (и шаблонов классов) и объявлений функций (и шаблонов функций). Если сделать это правильно, то реализация уже не так сложна. Однако на некоторые моменты все же стоит обратить
Общая реализация
Общая реализация Теперь посмотрим, как можно обобщить класс CDelegateVoid для применения с различными сигнатурами. Используя шаблоны, мы можем параметризовать как тип возвращаемого значения, так и типы параметров функций, на которые ссылаются делегаты. В то же время, мы не
11.2. Реализация
11.2. Реализация Во всех более-менее сложных C-программах требуется тщательно продумать организацию, чтобы сохранить модульность и обеспечить удобство сопровождения. Наша демонстрационная программа разделена на четыре главных исходных файла.В каждом исходном файле
7.3.2 Реализация
7.3.2 Реализация Реализующие slist функции в основном просты. Единственая настоящая сложность – что делать в случае ошибки, если, например, пользователь попытается get() что-нибудь из пустого списка. Мы обсудим это в #7.3.4. Здесь приводятся определения членов slist. Обратите
14.5. Реализация
14.5. Реализация Теперь мы приступим к реализации нашей оболочки, следуя тем идеям, которые обсуждались в предыдущем разделе. На рис. 14.9 показаны основные объекты, которыми манипулирует оболочка. Цель — это вопрос, подлежащий рассмотрению; Трасса — это цепочка,
12.10. РЕАЛИЗАЦИЯ
12.10. РЕАЛИЗАЦИЯ Обычно на этапе кодирования всплывают все неприятные проблемы, которые только можно себе представить. Чем больше проект, тем больше проблем. Вот почему первые три шага так важны.Если все из вышеописанных шагов полностью пройдены, то реализация программы