Тасклеты представлены с помощью структуры tasklet_struct
в следующем виде.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
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 для текущего процессора.• Список текущего процессора очищается путем присваивания значения нуль указателю на него.