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

на главную

Жанры

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

 wait_queue_head_t more_work;

 wait_queue_head_t work_done;

 struct workqueue_struct *wq; /* соответствующая структура

workqueue_struct */

 task_t *thread; /* соответствующий поток */

 int run_depth; /* глубина рекурсии функции run_workqueue */

};

Заметим, что каждый тип рабочих потоков имеет одну, связанную с этим типом структуру

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

Структуры для представления действий

Все рабочие потоки реализованы как обычные потоки пространства ядра, которые выполняют функцию

worker_thread
. После начальной инициализации эта функция входит в бесконечный цикл и переходит в состояние ожидания. Когда какие-либо действия ставятся в очередь, поток возвращается к выполнению и выполняет эти действия. Когда в очереди не остается работы, которую нужно выполнять, поток снова возвращается в состояние ожидания. Каждое действие представлено с помощью структуры
work_struct
, определенной в файле
<linux/workqueue.h>
. Эта структура показана ниже.

struct work_struct {

 unsigned long pending; /* ожидает ли это действие на выполнение? */

 struct list_head entry; /* связанный список всех действий */

 void (*func)(void*) ; /* функция-обработчик */

 void *data; /* аргумент функции-обработчика */

 void *wq_data; /* для внутреннего использования */

 struct timer_list timer; /* таймер, который используется для

очередей отложенных действий с задержками */

};

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

work_struct
из списка. Когда список становится пустым, поток переходит в состояние ожидания.

Давайте рассмотрим упрощенную основную часть функции

worker_thread
.

for (;;) {

 set_task_state(current, TASK_INTERRUPTIBLE);

 add_wait_queue(&cwq->more_work, &wait);

 if (list_empty(&cwq->worklist))

schedule;

 else

set_task_state(current, TASK_RUNNING);

 remove_wait_queue(&cwq->more_work, &wait);

 if (!list_empty(&cwq->worklist))

run_workqueue(cwq);

}

Эта

функция выполняет следующие действия в бесконечном цикле.

• Поток переводит себя в состояние ожидания (флаг состояния устанавливается в значение

TASK_INTERRUPTIBLE
), и текущий поток добавляется в очередь ожидания.

• Если связанный список действий пуст, то поток вызывает функцию

schedule
и переходит в состояние ожидания.

• Если список не пуст, то поток не переходит в состояние ожидания. Вместо этого он устанавливает свое состояние в значение

TASK_RUNNING
и удаляет себя из очереди ожидания.

• Если список не пустой, то вызывается функция

run_workqueue
для выполнения отложенных действий.

Функция
run_workqueue

Функция

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

while (!list_empty(&cwq->worklist)) {

 struct work_struct *work;

 void (*f)(void*);

 void *data;

 work = list_entry(cwq->worklist.next, struct work_struct, entry);

 f = work->func;

 data = work->data;

 list_del_init(cwq->worklist.next);

 clear_bit(0, &work->pending);

 f(data);

}

Эта функция просматривает в цикле все элементы списка отложенных действий и выполняет для каждого элемента функцию, на которую указывает поле

func
соответствующей структуры
workqueue_struct
. Последовательность действий следующая.

• Если список не пустой, получить следующий элемент списка.

• Получить указатель на функцию (поле

func
), которую необходимо вызвать, и аргумент этой функции (поле
data
).

• Удалить полученный элемент из списка и обнулить бит ожидания в структуре элемента.

• Вызвать полученную функцию.

• Повторить указанные действия.

Извините, если не понятно

Взаимоотношения между различными, рассмотренными в этом разделе структурами достаточно запутанные. На рис. 7.1 показана диаграмма, которая эти взаимоотношения поясняет.

Рис. 7.1. Соотношения между отложенными действиями, очередями, действий и рабочими потоками

На самом верхнем уровне находятся рабочие потоки. Может существовать несколько типов рабочих потоков. Для каждого типа рабочих потоков существует один рабочий поток для каждого процессора. Различные части ядра при необходимости могут создавать рабочие потоки. По умолчанию выполняются только рабочие потоки events (события). Каждый рабочий поток представлен с помощью структуры

cpu_workqueue_struct
. Структура
workqueue_struct
представляет все рабочие потоки одного типа.

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

Возвращение Безумного Бога 5

Тесленок Кирилл Геннадьевич
5. Возвращение Безумного Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Возвращение Безумного Бога 5

Холодный ветер перемен

Иванов Дмитрий
7. Девяностые
Фантастика:
попаданцы
альтернативная история
6.80
рейтинг книги
Холодный ветер перемен

Кровь, золото и помидоры

Распопов Дмитрий Викторович
4. Венецианский купец
Фантастика:
альтернативная история
5.40
рейтинг книги
Кровь, золото и помидоры

Наследник павшего дома. Том I

Вайс Александр
1. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том I

Книга 5. Империя на марше

Тамбовский Сергей
5. Империя у края
Фантастика:
альтернативная история
5.00
рейтинг книги
Книга 5. Империя на марше

Генерал Скала и сиротка

Суббота Светлана
1. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Генерал Скала и сиротка

Мимик нового Мира 14

Северный Лис
13. Мимик!
Фантастика:
юмористическое фэнтези
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 14

Стрелок

Астахов Евгений Евгеньевич
5. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Стрелок

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Сержант. Назад в СССР. Книга 4

Гаусс Максим
4. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сержант. Назад в СССР. Книга 4

Третий. Том 2

INDIGO
2. Отпуск
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 2

Боксер 2: назад в СССР

Гуров Валерий Александрович
2. Боксер
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боксер 2: назад в СССР

Вопреки судьбе, или В другой мир за счастьем

Цвик Катерина Александровна
Любовные романы:
любовно-фантастические романы
6.46
рейтинг книги
Вопреки судьбе, или В другой мир за счастьем

Кротовский, сколько можно?

Парсиев Дмитрий
5. РОС: Изнанка Империи
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Кротовский, сколько можно?