Архитектура встраиваемой ОС реального времени – CE 6.0
Многозадачность и планирование
Планирование является важным вопросом в любой ОСРВ. Во время планирование ядро поддерживает список приоритетов каждого потока в операционной системе (ОС). Каждый процесс может содержать несколько потоков, и каждый поток является траекторией выполнения. Система планирования управляет порядком в котором эти различные траектории выполнения выстраиваются, и позволяет траекториям взаимодействовать друг с другом предсказуемым образом.
Когда в системе планирования происходят прерывания, планировщик принимает прерывания в учет и реорганизует потоки соответствующим образом. Разработчик приложения может создать миниатюрную индивидуальную систему планирования внутри потока, используя в этом потоке нити. Планировщик использует квант времени для принятия решений планирования.
Рис. 6.8. Пример планирования потоков. Поток 1 имеет самый высокий приоритет и выполняется до завершения, потоки 2 и 3 имеют одинаковый приоритет и выполняются циклически по очереди
Как видно на рисунке 6.8, CE использует алгоритм квантования времени на основе приоритета для планирования выполнения потоков. Потоки с одинаковым приоритетом выполняются циклически по очереди: когда поток останавливает выполнение, выполняются все другие потоки с таким же приоритетом, прежде чем исходный поток сможет продолжить. Потоки с более низким приоритетом выполняются, только после того как все потоки с более высоким приоритетом закончатся или будут блокированы. Если выполняется поток, и разблокируется поток с более высоким приоритетом, то поток с более низким приоритетом немедленно приостанавливается и запускается поток с более высоким приоритетом.
Поток должен выполнятся в течение заданного интервала времени, называемого квантом.
- Обычно 100 миллисекунд
- Квант равный 0 означает, что квант никогда не закончится
- Поток может выполняться, пока не будет блокирован или прерван
- OEM может определить другой квант.
Поток выполняется пока:
- Не закончится его квант
- Он не будет прерван потоком с более высоким приоритетом
- Он будет блокирован конкуренцией за ресурсы, такой как доступ к критическому разделу, семафору, или объекту-мьютексу.
После того как поток использовал свой квант, и если какой-либо поток с тем же приоритетом готов к выполнению, текущий поток приостанавливается, и другой поток запускается на выполнение. Единственным исключением для этого будет ситуация, когда поток является потоком "выполняющимся до завершения", что означает, что квант потока равен 0. Потоки с квантом, заданным равным 0, никогда не прекращаются с истечением срока, и никогда не будут вытеснены потоками с таким же приоритетом.
В CE 6.0 по умолчанию используется квант времени 100 мс. Квант времени можно задавать между 1 и 100 мс. Планировщик выполняет задание с самым высоким приоритетом. Задачи с одинаковым приоритетом будут выполняться циклически друг за другом. Никакого алгоритма старения в планировщике не используется, поэтому возможна ситуация зависания (потоки или процессы с низким приоритетом, которые никогда не выполняются). Пользователям необходимо тщательно проектировать прикладные программы и благоразумно задавать уровни приоритетов, чтобы избежать зависания.
Уровни приоритета
CE предлагает 256 уровней приоритета, при этом нулевой обладает наивысшим приоритетом, а 255 является самым низким приоритетом. Многие более высокие уровни приоритета (с 247 и до нуля) присваиваются приложениям реального времени, драйверам, и системным процессам.
Чтобы помешать случайному приложению снизить производительность системы, OEM может ограничить использование всех уровней приоритета между 247 и нулем только определенными OEM приложениями. Используйте CeSetThreadPriority и SetThreadPriority для задания потоку уровня приоритета. Используйте CeGetThreadPriority и GetThreadPriority для извлечения уровня приоритета потока. Система уровней приоритета имеет четыре диапазона, показанные в таблице 6.3.
Диапазон | Описание |
---|---|
0 - 96 | Зарезервировано для приложений реального времени, расположенных выше драйверов. |
97 - 152 | Используется драйверами устройства на базе CE по умолчанию |
153 - 247 | Зарезервировано для приложений реального времени, расположенных ниже драйверов. |
248 - 255 | Отображается в приоритеты не реального времени. |
Инверсия приоритета
Инверсия приоритета происходит, когда мьютекс или критический раздел, удерживаемый потоком с более низким приоритетом, задерживает выполнение потока с более высоким приоритетом, когда они оба конкурируют за один и тот же ресурс.
Для мьютексов и критических разделов, чтобы исправить эту ситуацию и освободить поток с более высоким приоритетом с помощью наследования приоритета CE позволяет потоку с более низким приоритетом наследовать приоритет критически более важного потока и выполниться с более высоким приоритетом, пока он не освободит используемый им ресурс. Наследование приоритета не применяется к семафорам, которые не имеют связанного с ними определенного владельца.
Так как требуется неограниченный объем времени для освобождения инверсированного потока и это находится вне контроля ядра, то OEM теряет управление над планированием процесса. Чтобы гарантировать производительность реального времени, OEM должен гарантировать, что условие инверсии приоритета не возникает.
Рассмотрим пример, показанный на рисунке 6.9, который показывает, как система без наследования приоритета могла бы привести к плохому планированию потоков.
Предположим, что приложение имеет три потока:
- Поток 1 имеет высокий приоритет
- Поток 2 имеет средний приоритет
- Поток 3 имеет низкий приоритет
Поток 1 и поток 2 находятся в спящем режиме или блокированы в начале примера. Затем выполняется поток 3 и входит в критический раздел. В этот момент поток 2 начинает выполнение, вытесняя поток 3, так как поток 2 имеет более высокий приоритет. Поэтому поток 3 продолжает владеть критическим разделом.
Позже начинает выполнение поток 1, вытесняя поток 2. Поток 1 пытается войти в тот критический раздел, которым владеет поток 3, но так как им владеет другой поток, поток 1 блокируется, ожидая критический раздел.
В этом месте начнет выполняться поток 2, так как он имеет более высокий приоритет, чем поток 3, а поток 1 не выполняется. Поток 3 никогда не освободит критический раздел, который ожидает поток 1, так как поток 2 будет продолжать выполняться. Поэтому поток с самым высоким приоритетом в системе, поток 1, становится блокированным, ожидая выполнения потоков с более низкими приоритетами.
Чтобы разрешить проблему с потоками CE допускает наследование приоритета на глубину одного уровня. В предыдущем примере, когда поток 1 блокируется, так как он ждет завершения потока 3, CE повышает приоритет потока 3. Когда приоритет потока 3 повышается, он выполняется и, в конечном счете, освобождает общий ресурс для потока 1.
После освобождения потоком 3 общего ресурса, CE восстанавливает исходный приоритет потока 3, и затем выполняется поток 1.
Однако если поток 3 блокирован и ожидает, чтобы другой поток X освободил объект, CE не повышает приоритет потока X, который может быть потоком с самым низким приоритетом. Поддержка инверсии приоритета нескольких уровней будет иметь отрицательное влияние на производительность в реальном времени. Если приоритет потока инверсируется, поток получает новый квант, когда его приоритет больше не инверсирован.