Лабораторный практикум по курсу "Операционные системы"
Прежде, чем производить операции над очередью, ее необходимо заблокировать, временно
закрепив за собой исключительное право выполнения операций над ней. Для этого могут
использоваться, например, функции
static inline runqueue_t *lock_task_rq( task_t *p, ulong flags );
static inline void lock_task_rq(runqueue_t *rq, ulong flags );
Для избежания взаимоблокировок, в случае использование нескольких очередей, они
должны блокироваться в порядке возрастания адресов.
Каждая очередь процессов содержит два массива приоритетов – активный и истекший.
Каждый из этих массивов содержит один список процессов, готовых к исполнению, на
каждый уровень приоритета. Массив приоритетов также содержит битовую маску, в которой
содержатся признаки наличия
процессов с каждым уровнем приоритета.
struct prio_array {
int nr_active; /* число активных процессов */
spinlock_t *lock;/* указатель на признак блокировки очереди */
runqueue_t *rq; /* очередь – владелец массива */
unsigned long bitmap[BITMAP_SIZE]; /* битовый массив */
list_t queue[MAX_PRIO]; /* списки по приоритетам */
};
MAX_PRIO – максимальное число приоритетов в системе (по умолчанию, 140). Массив
приоритетов содержит битовый массив, в котором отведен бит для каждого уровня
приоритета. Изначально, все биты равны 0. Когда процесс с некоторым уровнем приоритета
переходит в состояние «готов к исполнению», соответствующий бит устанавливается в 1.
Таким образом, поиск процесса с наивысшим приоритетом сводится к поиску
первого бита в
данном массиве (sched_find_first_bit()) и взятию первого элемента из соответствующего
списка.
Кванты времени центрального процессора
Множество операционных систем, включая ранние версии Linux, производят вычисление
размеров квантов следующим образом:
for (each task on the system) {
recalculate priority
recalculate timeslice
}
Такой подход потенциально может занимать много времени, и может привести к
блокированию доступа к дескрипторам процессов на значительное время (блокировка
доступа к дескрипторам необходима).
Описываемая версия планировщика не требует подобного цикла пересчета. Вместо этого,
поддерживаются два массива приоритетов для каждого процессора: активный и истекший.
Активный массив содержит процессы, еще не использовавшие
полностью предоставленный
им квант времени, истекший – исчерпавшие свой квант. Когда размер кванта процесса
уменьшается до 0, производится перерасчет кванта, и процесс перемещается в истекший
104 Учебно-исследовательская лаборатория «Информационные технологии»