Rationale for Ada 2005: Tasking and Real-Time
RUSTOPBACKNEXT
ENG |
5. Scheduling and dispatching
@ Another area of increased flexibility in Ada 2005 is that of task dispatching policies. In Ada 95, the only predefined policy is FIFO_Within_Priorities although other policies are permitted. Ada 2005 provides further pragmas, policies and packages which facilitate many different mechanisms such as non-preemption within priorities, the familiar Round Robin using timeslicing, and the more recently acclaimed Earliest Deadline First (EDF) policy. Moreover it is possible to mix different policies according to priority level within a partition. @ In order to accommodate these many changes, Section D.2 (Priority Scheduling) of the Reference Manual has been reorganized as follows
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale for Ada 2005: Tasking and Real-Time
@ENGRUSTOPBACKNEXT5. Планирование и диспетчеризация
@ Другая область повышения гибкости в Аде 2005 является область политики диспетчеризации задач. На Аде 95 единственная предопределенная политика - FIFO_Within_Priorities, хотя и другая политика разрешена. Ада 2005 обеспечивает дальнейшие прагмы, политики и пакеты которые облегчают множество различных механизмов таких как неприоритетное прерывание в пределах приоритетов, знакомый Rround Robin, используя timeslicing, и позже приветствуемая политика Earliest Deadline First (EDF). Кроме того, возможно смешивать различные политики согласно приоритетному уровню в пределах разделения.
@ Чтобы упорядочить эти изменения, Секция D.2 (Планирование Приоритета) Справочного описания была реорганизована следующим образом:
@ Полный контроль предоставлен следующими двумя прагмами:
|
@ Прагма Task_Dispatching_Policy, которая уже существует в Аде 95 применяет ту же самую политику в течение целого разделения. Прагма Priority_Specific_Dispatching является новой в Аде 2005 и может использоваться чтобы установить различную политику для различных диапазонов приоритетных уровней.
@ Полный набор предопределенной политики в Аде 2005 - FIFO_Within_Priorities - Он уже, существует в Аде 95. В пределах каждого приоритетного уровня задачи выполняются в порядке очереди FIFO. Кроме того, задача может выгрузить задачу более низкого приоритета.
@ Non_Preemptive_FIFO_Within_Priorities - Это новое в Аде 2005. В пределах каждого приоритетного уровня задачи выполняются пока не завершатся или пока они не будут блокированы или выполнять оператор задержки.
@ Задача не может быть выгружена другой более высокого приоритета. Этот вид политики широко используется в приложениях высокой целостности.
@ Round_Robin_Within_Priorities - Это новое в Аде 2005. В пределах каждого приоритетного уровня каждая задача имеет свой временной интервал, который может быть определен. Это - очень традиционная политика, широко используемая с самых ранних дней параллельного программирования.
@ EDF_Across_Priorities - Это новое в Аде 2005. Оно обеспечивает механизм Earliest Deadline First (Самый ранний Крайний срок Сначала) диспетчеризации. Который состоит в том, что в пределах диапазона приоритетных уровней, у каждой задачи есть крайний срок до истечения которого задача должна быть отрабработана. Это - фешенебельная новая политика имеет математически доказуемые преимущества по эффективности.
@ Для детальной информации об этой политике обрящайтесь к книге Alan Burns and Andy Wellings [4].
@ Этой политикой управляет пакет Ada.Dispatching плюс два дочерних пакета. Корневой пакет имеет следующую спецификацию:
|
@ Как можнр видеть, этот корневой пакет просто объявляет исключение Dispatching_Policy_Error которое используется дочерними пакетами.
@ Дочерний пакет Round_Robin осуществляет регулировку квантов времени для квантования времени в пределах одного или более приоритетных уровней. Его спецификация:
|
@ Процедуры Set_Quantum позволяют кванту времени использоваться для квантования времени, которое будет установлено для одного или диапазона приоритетных уровней. Значение по умолчанию определяется константой Default_Quantum. Функция Actual_Quantum позволяет нам узнать текущее значение кванта, используемого для специфического приоритетного уровня. Его идентификатор отражает факт, что реализация, возможно, не в состоянии применить точное фактическое значение, данное в запросе Set_Quantum. Функция Is_Round_Robin позволяет нам проверить, была ли политика циклического алгоритма применена к данному уровню приоритета. Если мы пытаемся сделать нечто глупое, например установить квант для приоритетного уровня к которому политика циклического алгоритма не применима, тогда возбуждается исключение Dispatching_Policy_Error.
@ Другая новая политика касается пределов и управляется новой прагмой Relative_Deadline и дочернего пакета Dispatching.EDF. Синтаксис прагмы такой: pragma Relative_Deadline (relative_deadline_expression); Крайний срок задачи это свойство подобное приоритету, и они оба используются для планирование (scheduling). У каждой задачи есть приоритет типа Integer, и у каждой задачи есть крайний срок типа Ada.Real_Time.Time. Приоритеты могут быть установлены, когда задача создана прагмой pragma Priority:
|
@ и крайние сроки могут так же быть установлены прагмой Relative_Deadline таким образом:
|
@ У выражения RD типа Ada.Real_Time.Time_Span. Отметим, что прагма устанавливает родственника а не абсолютный крайний срок. Начальный абсолютный крайний срок задачи - Ada.Real_Time.Clock + RD, где запрос Clock сделан между созданием задачи и началом его активации.
@ Обе прагмы Priority и Relative_Deadline могут появиться в основной подпрограмме, и они тогда относятся к задаче среды. Если они появляются в любой другой подпрограмме тогда, они игнорируются. Оба свойства могут также быть установлены через дискриминант. В случае приоритетов мы можем написать:
|
@ Мы не можем сделать прямое назначение для пределов, потому что Time_Span является приватным и так не дискретный.
@ Мы должны использовать ссылочный дискриминант таким образом:
|
@ Отметим, что функции Seconds и Minutes были добавлены к пакету Ada.Real_Time. Существующие функции Nanoseconds, Microseconds и Milliseconds в Аде 95 осуществляют удобную спецификацию коротких интервалов реального времени (значения типа Time_Span). Однако, спецификация более длинных интервалов, таких как четыре минуты вынуждало писать Milliseconds (240_000) или возможно 4 * 60 * Milliseconds (1000). Ввиду факта, что планирование EDF и таймеры (см. Секцию 6), вероятно, потребовали бы более длинных времен, функции Seconds и Minutes добавлены к Аде 2005. Нет никакой функции Hours, потому что диапазон отрезков не предусматривает временных интервалов больше 3600 секунд так или иначе.
@ Если создаётся задача и у нее нет прагмы Priority тогда, его начальный приоритет равен приоритету задачи, которая её создаёт. Если у задачи нет прагмы Relative_Deadline тогда, его начальный абсолютный крайний срок равен константе Default_Deadline из пакета Ada.Dispatching.EDF; у этой константы есть значение Ada.Real_Time.Time_Last (эффективно конец области).
@ Приоритетами можно динамически управлять подпрограммами из пакета Ada.Dynamic_Priorities и пределами можно так же управлять подпрограммы из пакета Ada.Dispatching.EDF спецификация которого:
|
@ Подтип Dadline был объявлен только как удобное сокращение. Константа Default_Deadline установлена в конец области как было уже упомянуто. Процедура Set_Deadline устанавливает крайний срок соответствующей задачи к значению параметра D. Многословный Delay_Until_And_Set_Deadline задерживает соответствующую задачу до значения Delay_Until_Time, и устанавливает её крайний срок, чтобы быть интервальным Deadline_Offset с того времени - это полезно для периодических задач. Функция Get_Deadline позволяет нам найти текущий крайний срок задачи.
@ Важно отметить, что этот пакет может использоваться, чтобы установить и восстановить пределы для задач, являются ли они подлежащими диспетчеризации EDF. Мы могли например использовать ATC на переполненном крайнем сроке (ACT = Асинхронная Передача Контроля, используя оператора выбора). Следовательно нет никакой функции Is_EDF, соответствующей Is_Round_Robin, и запросы подпрограмм в этом пакете никогда не могут вызывать исключение Dispatching_Policy_Error.
@ Если мы пытаемся применить одну из подпрограмм в этом пакете к задаче, которая уже закончилась тогда возбуждается исключение Tasking_Error. Если параметр задачи - Null_Task_Id тогда возбуждается исключение Program_Error.
@ Как было упомянуто ранее, политика может быть выбрана для целого разделения например прагмой Task_Dispatching_Policy (Round_Robin_Within_Priorities); тогда чтобы смешать различные политики через различные приоритетные уровни мы можем написать:
|
@ Это устанавливает Циклический алгоритм (Round Robin) на уровень приоритета 1, EDF на уровени 2 - 10, и FIFO на уровнях 11 - 24. Это означает например, что ни одна из задач EDF не может работать, если имеется какая - нибудь задача в FIFO. Другими словами, если какие-нибудь задачи в самой высокой группе могут работать тогда, ни в одной другой группе не может осуществляться работа. Планирование в пределах диапазона вступает во владение, только если задачи ни в одном из более высоких диапазонов не могут работать.
@ Отметим это, если мы пишем:
|
@ тогда это не то же самое что:
|
@ несмотря на то, что два диапазона в первом случае являются смежными. Это - то, потому что в первом случае любая задача в этих 6 - 10 диапазонах будет иметь приоритет по любой задаче в этих 2 - 5 диапазонах вообще пределы. Если есть только один диапазон тогда только счет пределов в решении, какие задачи намечаются.
@ Это подчеркнуто тем фактом, что название политики использует термин Across (Через), а не Within (В пределах). Для другой политики, такой как Round_Robin_Within_Priority два смежных диапазона были бы тем же самым как одним диапазоном.
@ Мы заключаем эту секцию с несколькими словами о потолке приоритетов.
@ В Аде 95, может быть изменен приоритет задачи, но приоритет потолка защищенного объекта не может быть изменен. Это надолго установлено, когда объект создан, используя прагмы Priority. Это часто делается, используя дискриминант так, чтобы по крайней мере различные объекты данного защищенного типа могли иметь различные приоритеты. Таким образом мы могли бы написать:
|
@ Факт, что приоритет потолка защищенного объекта является статическим, может быть неприятностью во многих приложениях особенно, когда приоритет задач может быть динамическим. Общая работа должна дать защищенному объекту более высокий потолок чем необходимый при всех обстоятельствах (часто названный "потолок потолков"). Это приводит к задачам, имеющим более высокий активный приоритет чем необходимый, обращаясь к защищенному объекту, и это может столкнуться с обработкой других задач в системе и, таким образом, опрокинуть повсюду schedulability. Кроме того, это означает, что задача первоочередности может обратиться к объекту, когда это не должен (если задача с приоритетом выше чем приоритет потолка защищенного объекта пытается обратиться к объекту тогда, возбуждается исключение Program_Error если у объекта будет надутый приоритет тогда, то эта проверка пройдет, когда это не должно).
@ Эта трудность преодолена в Аде 2005, позволяя защищенным объектам изменить их приоритет. Это сделано через введение атрибута Priority, который применяется только к защищенным объектам. К этому можно только обратиться в пределах тела соответствующего защищенного объекта.
@ Как пример у защищенного объекта могла бы быть процедура, чтобы изменить ее приоритет потолка на некоторую величину. Это могло быть написано следующим образом:
|
@ Изменение приоритета потолка, таким образом, сделано, в то время как взаимное исключение находится в силе. Хотя значение самого атрибута немедленно изменено, присваивание сделано, фактический приоритет потолка защищенного объекта изменится только когда защищенная операция (в этом случае вызов Change_Priority) будет закончена.
@ Отметьте необычный синтаксис. Здесь мы разрешаем атрибут как адресат оператора присваивания.
@ Это еще не случалось нигде в языке. Рассматривались и другие формы синтаксиса, но это показалось самым выразительным.
2010-10-24 00:26:55
. .