В однопроцессорной системе Linux прерывание таймера не зависит от того, находится ли система в режиме ядра или пользовательском режиме?
Есть ли другое поведение для прерывания таймера, когда система находится в режиме ядра?
В однопроцессорной системе Linux прерывание таймера не зависит от того, находится ли система в режиме ядра или пользовательском режиме?
Есть ли другое поведение для прерывания таймера, когда система находится в режиме ядра?
Простой ответ заключается в том, что ни на выполнение процедуры обслуживания прерывания аппаратных часов, ни на планирование обработчиков динамического таймера не влияет режим, в котором находилась система до прерывания аппаратных часов. Причина в том, что прерывание по тактовому таймеру является аппаратным прерыванием, которое обслуживается немедленно, независимо от того, происходит ли выполнение в контексте ядра или пользователя (при условии, что прерывание по таймеру включено), а процедура обслуживания прерывания для прерывания по тактовому таймеру сам вызывает программное прерывание, которое запускает обработчики динамического таймера.
Предостережение: 1) Я на самом деле не доказал это эмпирически. 2) Это не относится к бестактным ядрам или таймерам высокого разрешения.
В коде ядра Linux слово «таймер» используется для обозначения нескольких разных вещей:
Аппаратные часы или таймер
В системах, которые используют аппаратные часы для обеспечения тика, прерывание таймера часов является аппаратным прерыванием, зависящим от архитектуры. Например, найдите timer_interrupt в arch/powerpc. /kernel/head_booke.h, а затем просмотрите реализацию процедуры обслуживания прерываний (ISR) timer_interrupt в arch/powerpc/kernel/time.c. Этот ISR выполняется немедленно, когда происходит прерывание таймера, независимо от текущего контекста выполнения. Это аппаратное прерывание отличается от других аппаратных прерываний тем, что когда оно возвращается, обработка не возвращается к предыдущему контексту. Вместо этого вводится планировщик.
Для системы, настроенной на создание 1000 прерываний часов в секунду, есть вероятность, что прерывания часов будут иногда маскироваться, когда обслуживаются другие прерывания. Обычно это называют проблемой потерянных тиков. Без компенсации потерянных тиков загруженная система может иметь замедленное чувство времени. В некоторых архитектурах ядро компенсирует потерянные тики с помощью более точного аппаратного счетчика приращений, значение которого считывается и записывается при каждом прерывании тактового таймера. Сравнивая значение счетчика приращения текущего тика со значением счетчика приращения предыдущего тика, ядро может сказать, был ли потерян такт.
Программные таймеры
Список обработчиков динамических таймеров (тип, который вы задали с помощью linux/timer.h) динамических таймеров с истекшим сроком действия устанавливается в конце прерывания тактового таймера перед его возвратом. Последовательность такая (приблизительно):
[arch dependent]:timer_interrupt( )
kernel/time/tick-common.c:tick_handle_periodic( )
kernel/time/tick-common.c:tick_periodic( )
kernel/timer.c:update_process_times( )
kernel/timer.c:run_local_timers( )
kernel/softirq.c:raise_softirq(TIMER_SOFTIRQ)
Я пропустил инициализации, которые устанавливали обработчик для timer_interrupt в tick_handle_periodic, а обработчик для TIMER_SOFTIRQ.
Вызов raise_softirq(TIMER_SOFTIRQ) генерирует программное прерывание, которое немедленно обслуживается. ISR для прерывания запускает очередь динамического таймера. Обработчики таймеров работают в контексте softirq с включенными аппаратными прерываниями. Когда ISR возвращается, вызывается планировщик. Это означает, что если установлено много таймеров, любой процесс, который окажется следующим в очереди выполнения, будет задержан.
Если были потерянные тики, то выполнение обработчиков таймера могло быть задержано, однако задержка не зависит от контекста выполнения до запуска прерывания часового таймера.
Примечание о точности динамического таймера
...ядро не может гарантировать, что функции таймера запустятся прямо в момент истечения срока их действия. Он может только обеспечить их выполнение либо в нужное время, либо позже с задержкой до нескольких сотен миллисекунд. Понимание ядра Linux, Bovet and Cesati, 3-е издание, O'reilly.
Итак, если вам нужна более высокая точность таймера, вам нужно использовать таймеры с высоким разрешением.
Ссылки: Программные прерывания и режим реального времени