Pages Menu
Categories Menu

Опубликовано | Нет комментариев

Истечение времени таймера

Как уже говорилось, основной задачей ISR-процедуры, связанной с прерыванием, генерируемым RTC или PIT, является отслеживание системного времени, которое в основном выполняется процедурой KeUpdateSystemTime.

Ее второе задание заключается в отслеживании логического времени выполнения, например, времени выполнения процесса или потока, и системного времени такта, которое является базовым показателем, используемым такими API-функциями, как GetTickCount, которые, в свою очередь, используются разработчиками для операций со временем в их приложениях. Эта часть работы выполняется процедурой KeUpdateRunTime. Но перед выполнением любой из этих работ, процедура KeUpdateRunTime проверяет, не истекло ли время какого-либо таймера.

Таймеры Windows могут быть либо абсолютными таймерами, что предполагает в будущем определенный показатель истечения времени, либо относительными таймерами, которые содержат отрицательное значение истечения срока, используемое как положительное смещение от текущего времени при вводе таймера в действие. Внутри системы все таймеры преобразуются к абсолютному времени истечения срока, хотя система следит за тем, является ли это время «настоящим» абсолютным временем или преобразованным относительным временем.

Эта разница важна в некоторых сценариях, например, в таких, как переход на летнее время (или даже изменение показаний часов вручную).

Если пользователь перевел часы с 13 часов на 19 часов, абсолютный таймер все равно выдаст сигнал в «20 часов», а вот относительный таймер, настроенный, скажем, на истечение времени «через 2 часа», не почувствует влияния изменения показания часов, поскольку 2 часа еще не прошли. При возникновении подобных событий изменения системного времени ядро перепрограммирует абсолютное время, связанное с относительными таймерами, чтобы оно соответствовало новым установкам.

Поскольку часы выдают сигнал через известный кратный интервал, нижние разряды текущего системного времени будут в одной из 64 известных позиций (на APIC HAL). Windows использует это обстоятельство для сведения всех таймеров драйверов и приложений в связанные списки на основе массива, в котором каждый элемент соответствует возможному кратному показателю системного времени.

Эта таблица, называемая таблицей таймера, находится в блоке управления областью процессора — PRCB, что позволяет каждому процессору представлять свое собственное независимое истечение времени таймера без необходимости запроса глобальной блокировки.

Далее будет показано, чем определяется таблица таймера логического процессора, в которую вставляется таймер. Поскольку таблица таймера есть у каждого процессора, работа по истечении времени таймера проделывается каждым процессором.

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

пример-таймерных-списков

Хотя обновление счетчиков и проверка связанного списка являются быстрыми операциями, проход по каждому таймеру и изменение срока истечения его времени представляет из себя потенциально затратную операцию, ведь следует иметь в виду, что вся эта работа в настоящее время выполняется на уровне CLOCK_LEVEL, то есть на исключительно высоком IRQL-уровне.

Аналогично тому, как ISR-процедура драйвера выстраивает в очередь DPC, чтобы отсрочить работу, ISR-процедура часов запрашивает программное прерывание DPC, устанавливает флаг в PRCB, чтобы механизм истощения DPC знал о том, что таймеры нуждаются в истечении срока своей работы.

Точно так же, при обновлении времени выполнения процесса или потока, если ISR-процедура часов определяет, что у потока закончился квант времени, она также ставит в очередь программное прерывание DPC и устанавливает другой PRCB флаг. Эти флаги имеются у каждой PRCB-области, поскольку каждый процессор обычно совершает свои собственные вычисления по обновлению времени выполнения, так как каждый процессор выполняет индивидуальный поток и имеет различные связанные с ним задачи. В таблице показаны различные поля, используемые при обработке таймера и истечении срока его работы.

Как только IRQL в рамках обработки DPC снова снизится до уровня DISPATCH_LEVEL, эти два флага будут установлены.

Поля KPRCB, относящиеся к обработке таймера.

поля-KPRCB

Здесь будет рассмотрена работа по истечении времени таймера. Поскольку таймеры связаны друг с другом исполнителем, код истечения времени (исполняемый DPC-вызовом, связанным с PRCB в поле TimerExpiryDpc) проводит разбор этого списка с головы до хвоста. (Во время ставки таймеры, ближайшие к значению, кратному интервалу часов, будут первыми, а за ними последуют таймеры, которые все ближе и ближе к следующему интервалу, но еще находящиеся в пределах данного исполнителя.)

Для истечения времени таймера нужно выполнить две основные задачи:

  • Таймер рассматривается как объект синхронизации диспетчера (потоки ждут таймера в рамках истечения лимита времени или непосредственно в рамках ожидания). На таймере будут запущены алгоритмы тестирования ожидания и удовлетворения ожидания. Эта работа рассмотрена далее в разделе, посвященном синхронизации. Именно таким образом таймер используется приложениями пользовательского режима и некоторыми драйверами.
  • Таймер рассматривается как объект управления, связанный с процедурой обратного DPC-вызова, которая выполняется по истечении времени таймера. Этот метод зарезервирован только для драйверов и обеспечивает очень быструю реакцию на истечение времени таймера. (Метод ожидания/диспетчеризации требует задействовать всю дополнительную логику сигнализации ожидания.) Кроме того, поскольку само истечение времени таймера выполняется на уровне DISPATCH_LEVEL, на котором также запускаются DPC-процедуры, для процедуры обратного вызова таймера складываются весьма благоприятные обстоятельства.

Как только каждый процессор привлекается к обслуживанию таймера тактового интервала для выполнения обработки системного времени и времени выполнения, он также обрабатывает истечение времени таймера после небольшой задержки, во время которой IRQL-уровень снижается с CLOCK_LEVEL до DISPATCH_LEVEL.

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

истечение-времени-таймера

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Лимит времени истёк. Пожалуйста, перезагрузите CAPTCHA.

↓