Чтение онлайн

на главную

Жанры

Разработка ядра Linux
Шрифт:

• Проверяется значение поля

count
на равенство нулю, чтобы убедиться, что тасклет не запрещен. Если тасклет запрещен (поле count не равно нулю), то нужно перейти к следующему тасклету, который ожидает на выполнение.

• Теперь можно быть уверенным, что тасклет нигде не выполняется, нигде не будет выполняться (так как он помечен как выполняющийся на данном процессоре) и что значение поля count равно нулю. Необходимо выполнить обработчик тасклета. После того как тасклет выполнился, следует очистить флаг

TASLET_STATE_RUN
и поле
state
.

• Повторить описанный алгоритм для следующего тасклета, пока не останется ни одного тасклета, ожидающего выполнения.

Реализация

тасклетов проста, но в то же время очень остроумна. Как видно, все тасклеты реализованы на базе двух отложенных прерываний
TASKLET_SOFTIRQ
и
HI_SOFTIRQ
. Когда тасклет запланирован на выполнение, ядро генерирует одно из этих двух отложенных прерываний. Отложенные прерывания, в свою очередь, обрабатываются специальными функциями, которые выполняют все запланированные на выполнение тасклеты. Эти специальные функции гарантируют, что только один тасклет данного типа выполняется в любой момент времени (но тасклеты разных типов могут выполняться одновременно). Вся эта сложность спрятана за простым и ясным интерфейсом.

Использование тасклетов

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

Объявление тасклетов

Тасклеты можно создавать статически и динамически. Какой вариант лучше выбрать, зависит от того, как необходимо (или желательно) пользователю обращаться к тасклету: прямо или через указатель. Для статического создания тасклета (и соответственно, обеспечения прямого доступа к нему) необходимо использовать один из двух следующих макросов, которые определены в файле

<linux/interrupts.h>
:

DECLARE_TASKLET(name, func, data);

DECLARE_TASKLET_DISABLED(name, func, data);

Оба макроса статически создают экземпляр структуры

struct_tasklet_struct
с указанным именем (
name
). Когда тасклет запланирован на выполнение, то вызывается функция
func
, которой передается аргумент
data
. Различие между этими макросами состоит в значении счетчика ссылок на тасклет (поле
count
). Первый макрос создает тасклет, у которого значение поля count равно нулю, и, соответственно, этот тасклет разрешен. Второй макрос создает тасклет и устанавливает для него значение поля
count
, равное единице, и, соответственно, этот тасклет будет запрещен. Можно привести следующий пример.

DECLARE_TASKLET(my_tasklet, my_tasklet_handler, dev);

Эта строка эквивалентна следующей декларации.

struct tasklet_struct my_tasklet = {

 NULL, 0, ATOMIC_INIT(0), tasklet_handler, dev

};

В данном примере создается тасклет с именем

my_tasklet
, который разрешен для выполнения. Функция
tasklet_handler
будет обработчиком этого тасклета. Значение параметра
dev
передается в функцию-обработчик при вызове данной функции.

Для инициализации тасклета, на который указывает заданный указатель

struct tasklet_struct* t
— косвенная ссылка на динамически созданную ранее структуру, необходимо использовать следующий вызов.

tasklet_init(t, tasklet_handler, dev); /* динамически, а не статически */

Написание собственной функции-обработчика тасклета

Функция-обработчик тасклета должна соответствовать правильному прототипу.

void tasklet_handler(unsigned long data);

Так

же как и в случае отложенных прерываний, тасклет не может переходить в состояние ожидания (блокироваться). Это означает, что в тасклетах нельзя использовать семафоры или другие функции, которые могут блокироваться. Тасклеты также выполняются при всех разрешенных прерываниях, поэтому необходимо принять все меры предосторожности (например, может понадобиться запретить прерывания и захватить блокировку), если тасклет имеет совместно используемые данные с обработчиком прерывания. В отличие от отложенных прерываний, ни один тасклет не выполняется параллельно самому себе, хотя два разных тасклета могут выполняться на разных процессорах параллельно. Если тасклет совместно использует данные с обработчиком прерывания или другим тасклетом, то необходимо использовать соответствующие блокировки (см. главу 8, "Введение в синхронизацию выполнения кода ядра" и главу 9, "Средства синхронизации в ядре").

Планирование тасклета на выполнение

Для того чтобы запланировать тасклет на выполнение, должна быть вызвана функция

tasklet_schedule
, которой в качестве аргумента передается указатель на соответствующий экземпляр структуры
tasklet_struct
.

tasklet_schedule(&my_tasklet); /* отметить, что тасклет my_tasklet

ожидает на выполнение */

После того как тасклет запланирован на выполнение, он выполняется один раз в некоторый момент времени в ближайшем будущем. Если тасклет, который запланирован на выполнение, будет запланирован еще раз до того, как он выполнится, то он также выполнится всего один раз. Если тасклет уже выполняется, скажем, на другом процессоре, то будет запланирован снова и снова выполнится. Для оптимизации тасклет всегда выполняется на том процессоре, который его запланировал на выполнение, что дает надежду на лучшее использование кэша процессора.

Указанный тасклет может быть запрещен с помощью вызова функции

tasklet_disable
. Если тасклет в данный момент времени выполняется, то эта функция не возвратит управление, пока тасклет не закончит выполняться. Как альтернативу можно использовать функцию
tasklet_disable_nosync
, которая запрещает указанный тасклет, но возвращается сразу и не ждет, пока тасклет завершит выполнение. Это обычно небезопасно, так как в данном случае нельзя гарантировать, что тасклет не закончил выполнение. Вызов функции
tasklet_enable
разрешает тасклет. Эта функция также должна быть вызвана для того, чтобы можно было использовать тасклет, созданный с помощью макроса
DECLARE_TASKLET_DISABLED
, как показано в следующем примере.

tasklet_disable(&my_tasklet); /* тасклет теперь запрещен */

/* Мы можем делать все, что угодно, зная,

что тасклет не может выполняться. */

tasklet_enable(&my_tasklet); /* теперь тасклет разрешен */

Из очереди тасклетов, ожидающих на выполнение, тасклет может быть удален с помощью функции

tasklet_kill
. Эта функция получает указатель на соответствующую структуру
tasklet_struct
в качестве единственного аргумента. Удаление запланированного на выполнение тасклета из очереди очень полезно в случае, когда используются тасклеты, которые сами себя планируют на выполнение. Эта функция сначала ожидает, пока тасклет не закончит выполнение, а потом удаляет его из очереди. Однако это, конечно, не может предотвратить возможности, что другой код запланирует этот же тасклет на выполнение. Так как данная функция может переходить в состояние ожидания, то ее нельзя вызывать из контекста прерывания.

Поделиться:
Популярные книги

Хозяйка лавандовой долины

Скор Элен
2. Хозяйка своей судьбы
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Хозяйка лавандовой долины

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Идеальный мир для Лекаря 26

Сапфир Олег
26. Лекарь
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 26

Последняя Арена 10

Греков Сергей
10. Последняя Арена
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Последняя Арена 10

Батя

Черникова Саша
1. Медведевы
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Батя

Ваше Сиятельство 2

Моури Эрли
2. Ваше Сиятельство
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Ваше Сиятельство 2

Герцог и я

Куин Джулия
1. Бриджертоны
Любовные романы:
исторические любовные романы
8.92
рейтинг книги
Герцог и я

Газлайтер. Том 18

Володин Григорий Григорьевич
18. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 18

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11

Аристократ из прошлого тысячелетия

Еслер Андрей
3. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Аристократ из прошлого тысячелетия

Приручитель женщин-монстров. Том 3

Дорничев Дмитрий
3. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 3

Я тебя не отпущу

Коваленко Марья Сергеевна
4. Оголенные чувства
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Я тебя не отпущу

Любимая учительница

Зайцева Мария
1. совершенная любовь
Любовные романы:
современные любовные романы
эро литература
8.73
рейтинг книги
Любимая учительница

Лорд Системы 3

Токсик Саша
3. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 3