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

на главную - закладки

Жанры

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

Например, давайте будем считать, что в дополнение к обычному типу рабочих потоков events был создан еще один тип рабочих потоков — falcon. Также имеется в распоряжении четырехпроцессорный компьютер. Следовательно, выполняется четыре потока типа events (соответственно, определено четыре экземпляра структуры

cpu_workqueue_struct
) и четыре потока типа falcon (для которых тоже определены другие четыре экземпляра структуры
cpu_workqueue_struct
). Для потоков типа events определен один
экземпляр структуры
workqueue_struct
, а для потоков типа falcon — другой экземпляр этой структуры.

На самом нижнем уровне находятся отложенные действия. Драйвер создает отложенное действие, которой должно выполниться позже. Действия представлены структурами

work_struct
. Кроме других полей, эта структура содержит указатель на функцию, которая должна обработать отложенное действие. Отложенное действие отправляется на выполнение определенному потоку. Соответствующий поток переводится в состояние выполнения и выполняет отложенную работу.

Большинство драйверов использует существующие по умолчанию рабочие потоки, которые называются events. Они просты в реализации и в использовании. Однако в некоторых, более серьезных ситуациях необходимо создавать новые специальные рабочие потоки. Например, драйвер файловой системы XFS создает два новых типа рабочих потоков.

Использование очередей отложенных действий

Использовать очереди действий просто. Сначала мы рассмотрим рабочие потоки, используемые по умолчанию, — events, а затем опишем создание новых типов рабочих потоков.

Создание отложенных действий

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

DECLARE_WORK(name, void (*func)(void*), void *data);

Это выражение создает структуру

work_struct
с именем
name
, с функцией- обработчиком
func
и аргументом функции-обработчика
data
.

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

INIT_WORK(struct work_struct *work, void (*func)(void*), void *data);

Этот макрос динамически инициализирует отложенное действие, на структуру которого указывает указатель

work
, устанавливая функцию-обработчик
func
и аргумент
data
.

Обработчик отложенного действия

Прототип обработчика отложенного действия имеет следующий вид.

void work_handler(void *data);

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

Блокировки между

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

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

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

schedule_work(&work);

Действие планируется на выполнение немедленно и будет выполнено, как только рабочий поток

events
, работающий на данном процессоре, перейдет в состояние выполнения.

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

schedule_delayed_work(&work, delay);

В этом случае действие, представленное структурой

work_struct
, с адресом
&work
, не будет выполнено, пока не пройдет хотя бы заданное в параметре
delay
количество импульсов таймера. О том, как использовать импульсы таймера для измерения времени, рассказывается в главе 10, "Таймеры и управление временем".

Ожидание завершения действий

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

Для этого есть следующая функция, которая позволяет ждать, пока очередь действий events не будет очищена.

void flush_scheduled_work(void);

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

Заметим, что эта функция не отменяет никаких отложенных действий с задержками. Любые действия, которые запланированы на выполнение с помощью функции

schedule_delayed_work
и задержки которых еще не закончены, — не очищаются с помощью функций
flush_scheduled_work
. Для отмены отложенных действий с задержками следует использовать функцию

int cancel_delayed_work(struct work_struct *work);

Эта функция отменяет отложенное действие, которое связано с данной структурой

work_struct
, если оно запланировано.

Создание новых очередей отложенных действий

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

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

На границе тучи ходят хмуро...

Кулаков Алексей Иванович
1. Александр Агренев
Фантастика:
альтернативная история
9.28
рейтинг книги
На границе тучи ходят хмуро...

Энфис. Книга 1

Кронос Александр
1. Эрра
Фантастика:
боевая фантастика
рпг
5.70
рейтинг книги
Энфис. Книга 1

Я – Орк. Том 4

Лисицин Евгений
4. Я — Орк
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 4

Совок-8

Агарев Вадим
8. Совок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Совок-8

Я снова не князь! Книга XVII

Дрейк Сириус
17. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я снова не князь! Книга XVII

Жена со скидкой, или Случайный брак

Ардова Алиса
Любовные романы:
любовно-фантастические романы
8.15
рейтинг книги
Жена со скидкой, или Случайный брак

Адепт: Обучение. Каникулы [СИ]

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.15
рейтинг книги
Адепт: Обучение. Каникулы [СИ]

Огненный князь 6

Машуков Тимур
6. Багряный восход
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Огненный князь 6

Как я строил магическую империю 2

Зубов Константин
2. Как я строил магическую империю
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Как я строил магическую империю 2

Цеховик. Книга 1. Отрицание

Ромов Дмитрий
1. Цеховик
Фантастика:
попаданцы
альтернативная история
5.75
рейтинг книги
Цеховик. Книга 1. Отрицание

Безымянный раб

Зыков Виталий Валерьевич
1. Дорога домой
Фантастика:
фэнтези
9.31
рейтинг книги
Безымянный раб

Матабар. II

Клеванский Кирилл Сергеевич
2. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар. II

Виконт. Книга 2. Обретение силы

Юллем Евгений
2. Псевдоним `Испанец`
Фантастика:
боевая фантастика
попаданцы
рпг
7.10
рейтинг книги
Виконт. Книга 2. Обретение силы

Первый пользователь. Книга 3

Сластин Артем
3. Первый пользователь
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Первый пользователь. Книга 3