В предыдущем подразделе мы касались специфики динамического расчета приоритетов задач. Приоритет задачи основан на ее поведении в прошлом, а также на определенном пользователем значении nice. Функцией, динамически определяющей новый приоритет задачи, является recalc_task_prio ():
383 384 385 386 387 388 389 390 391 392 393 394
- p->timestamp;
unsigned long long sleep_time = now
unsigned long sleep_time;
if ( sleep_time > NS_MAX_SLEEP_AVG)
sleep_time = NS_MAX_SLEEP_AVG; else
sleep_tirae = (unsigned long) sleep_time;
if (likely(sleep_time > 0)) { /*
* Слишком долго спавшая задача категоризируется как
* простаивающая и получает статус интерактивной для того, чтобы
CREDIT(p))
p->interactive_credit++; } else {
Чем меньше sleep avg задачи,
sleep_time
1;
тем чаще увеличивается ее время сна.
(MAX_BONUS - CURRENT_BONUS(p)) ?
* Задача с низким значением интерактивности ограничивается
* одним временным срезом в размере бонуса sleep avg. */
if (LOW_CREDIT(p) && sleep_time > JIFFIES_TO_NS(task_timeslice(p))) sleep_time = JIFFIES_TO_NS(task_timeslice(p));
/*
* Задачи без high_credit, пробуждающиеся от беспрерывного
* сна, ограничиваются в росте sleep_avg, так как они
* смогут заблокировать процессор, ожидая ввода-вывода */
if (p->activated == -1 && !HIGH_CREDIT(р) && p->mm) { if (p->sleep_avg >= INTERACTIVE_SLEEP(p))
sleep_time = 0; else if (p->sleep_avg + sleep_time >= INTERACTIVE_SLEEP(p)) { p->sleep_avg = INTERACTIVE_SLEEP(p); sleep_time = 0;
}
}
Этот код награждает бонусом интерактивные задачи.
Это награждение работает с помощью обновления значения 'average sleep time' на основе ->timestamp. Чем больше времени задача тратит на сон, тем больше average -и выше получаемый приоритет.
Строки 386-389
На основе времени now мы рассчитываем длительность времени, в течение которого будет спать процесс р, и назначаем sleep_time максимальное значение NS_MAX_SLEEP_AVG. (По умолчанию NS_MAX_SLEEP_AVG равняется 10 мс.)
Строки 391-404
Если процесс р спит, мы сначала проверяем, спит ли он достаточно для того, чтобы задачу можно было классифицировать как интерактивную. Если это так, мы изменяем среднее время сна процесса с помощью sleep_time->lNTERACTlVE_ SLEEP (р), а если р классифицируется не как интерактивный процесс, мы увеличиваем interactive_cred.it для р.
Строки 405-410
Задача с меньшим временем сна получает большее время сна.
Строки 411-418
Если задача интенсивно нагружает процессор и она классифицирована не как интерактивная, мы ограничиваем процесс как минимум одним временным срезом, равным бонусу в виде среднего времени сна.
Строки 419-432
Задачи, еще не классифицированные как интерактивные (без HIGH_CREDIT), разбуженные от беспрерывного сна, и получают среднее время сна INTERACTIVE ().
Строки 434-450
Мы добавляем новое рассчитанное sleep_time к среднему времени сна процесса, проверяя, чтобы оно не превысило NS_MAX_SLEEP_AVG. Если процессы не признаны интерактивными, но спали максимальное время, мы увеличиваем их значение интерактивности.
Строка 452
Наконец, приоритет устанавливается с помощью ef f ective_prio () с учетом нового рассчитанного поля sleep_avg для р. Это делается с помощью масштабирования среднего времени от 0 до MAX_SLEEP_AVG в диапазоне от -5 до +5. Поэтому процесс со статическим приоритетом 70 может иметь динамический приоритет в пределах от 65 до 85, в зависимости от своего поведения в прошлом.
И еще одна финальная черта: процесс, не являющийся процессом реального времени, попадает в диапазон от 101 до 140. Процессы, обрабатываемые с большим приоритетом, попадают в диапазон 105 и ниже, хотя и не могут перевалить за барьер процессов реального времени. Поэтому интерактивный процесс с большим приоритетом может никогда не иметь динамического приоритета ниже 101. (В конфигурации по умолчанию процессы реального времени покрывают диапазон от 0 до 100.)