Разработка ядра Linux | страница 58
>schedule()
.>struct prio_array array = rq->active;
>if (!array->nr_active) {
> rq->active = rq->expired;
> rq->expired = array;
>}
Упомянутая перестановка и есть ключевым, моментом O(1)-планировщика. Вместо того чтобы все время пересчитывать значение приоритета и кванта времени для каждого процесса, O(1)-планировщик выполняет простую двухшаговую перестановку массивов. Такая реализация позволяет решить указанные выше проблемы.
>schedule()
Все действия по выбору следующего задания на исполнение и переключение на выполнение этого задания реализованы в виде функции >schedule()
. Эта функция вызывается явно кодом ядра при переходе в приостановленное состояние (sleep), a также в случае когда какое-либо задание вытесняется. Функция >schedule()
выполняется независимо каждым процессором. Следовательно, каждый процессор самостоятельно принимает решение о том, какой процесс выполнять следующим.
Функция >schedule()
достаточно проста, учитывая характер тех действий, которые она выполняет. Следующий код позволяет определить задачу с наивысшим приоритетом.
>struct task_struct *prev, *next;
>struct list_head *queue;
>struct prio_array *array;
>int idx;
>prev = current;
>array = rq->active;
>idx = sched_find_first_bit(array->bitmap);
>queue = array->queue + idx;
>next = list_entry(queue->next, struct task struct, run_list);
Вначале осуществляется поиск в битовой маске активного массива приоритетов для нахождения номера самого первого установленного бита. Этот бит соответствует готовой к выполнению задаче с наивысшим приоритетом. Далее планировщик выбирает первое задание из списка заданий, которое соответствует найденному значению приоритета. Это и есть задача с наивысшим значением приоритета в системе, и эту задачу планировщик будет запускать на выполнение. Все рассмотренные операции показаны на рис. 4.2.