Операционные системы
Real-Time системы
1997 год. Mars Pathfinder на поверхности Марса начинает внезапно перезагружаться. Миссия за 265 миллионов под угрозой. Причина? Priority inversion - баг планировщика RTOS. Инженеры NASA загружают патч через радио (300 млн км!), включают priority inheritance, ровер работает. Real-Time системы - это не просто «быстрый код». Это математические гарантии, что критичная задача выполнится ДО deadline. Пропуск deadline в airbag = смерть. В nuclear reactor = катастрофа. RT OS спасают жизни каждый день.
- **Mars Pathfinder (1997):** Priority inversion роняла систему на Марсе. Патч с priority inheritance спас миссию. Классический case study FAANG интервью.
- **Automotive safety (Tesla, Waymo):** PREEMPT_RT Linux для ADAS (camera → decision за <10ms). ISO 26262 ASIL D требует формального доказательства WCET.
- **Medical devices (pacemakers):** FreeRTOS на ARM Cortex-M. Hard RT гарантии: сердечный импульс ТОЧНО через 1000ms ±10μs. Пропуск = остановка сердца.
Цели урока
- Различать hard vs soft real-time; deadline vs throughput как метрики
- Real-time schedulers: Rate Monotonic, EDF (Earliest Deadline First)
- Priority inversion: проблема, priority inheritance, priority ceiling protocol
- PREEMPT_RT patch: spinlock → mutex, threaded IRQs, превращение Linux в RTOS
- WCET (Worst Case Execution Time) analysis и почему этот анализ нетривиален
Real-Time планирование
**Real-Time Operating System (RTOS)** - это операционная система, гарантирующая выполнение задач в строго определённые временные рамки. Отличие от обычных OS не в скорости, а в **детерминированности** - предсказуемости времени выполнения.
Разница между Fast OS и Real-Time OS
Обычная OS может обработать запрос за 5мс в среднем, но иногда за 500мс (если пришла прерывание, запустился garbage collector, вытеснил другой процесс). RTOS **гарантирует**: задача с deadline 10мс выполнится за максимум 10мс. Даже если средняя задержка выше, но верхняя граница строго соблюдается. Для авионики это разница между жизнью и смертью.
Real-time системы делятся на два типа: **Hard Real-Time** - пропуск deadline катастрофичен (авиация, медицина, ядерные реакторы). Пример: пропуск такта управления турбиной самолёта на 1мс → отказ двигателя. **Soft Real-Time** - пропуск deadline нежелателен, но не фатален (видеостриминг, VoIP). Пример: задержка пакета видео на 50мс → артефакт на экране, но система работает.
**RT планировщики используют priority-based preemptive scheduling.** Каждой задаче назначается приоритет. Планировщик всегда выполняет задачу с наивысшим приоритетом. Если приходит более приоритетная задача - текущая немедленно вытесняется (preemption).
**Linux RT policies:** - **SCHED_FIFO:** Fixed priority, no time slicing. Выполняется пока не заблокируется или не придёт более приоритетная задача. - **SCHED_RR:** Round-Robin с фиксированным приоритетом. Задачи с одинаковым приоритетом чередуются через time quantum. - **SCHED_DEADLINE:** Earliest Deadline First (EDF). Планировщик выбирает задачу с ближайшим deadline.
**Rate Monotonic Scheduling (RMS)** - классический алгоритм для периодических RT задач. Правило: задачи с меньшим периодом получают более высокий приоритет. Математически доказано оптимальным для static priority scheduling при определённых условиях.
В чём ключевое отличие Hard Real-Time системы от обычной High-Performance системы?
Priority Inversion
**Priority Inversion (инверсия приоритетов)** - катастрофическая проблема RT систем, когда высокоприоритетная задача блокируется низкоприоритетной через shared resource. Может привести к пропуску deadline и отказу системы.
Mars Pathfinder: реальный баг Priority Inversion
1997 год. NASA Mars Pathfinder на Марсе начал внезапно перезагружаться. **Причина:** Priority inversion в VxWorks RTOS. - Задача высокого приоритета: `bc_dist` (коммуникация с Землёй) - Задача низкого приоритета: `ASI/MET` (сбор метеоданных) - Shared resource: `information bus` (mutex) `ASI/MET` захватывала mutex → средние задачи вытесняли её → `bc_dist` ждала mutex → watchdog reset → перезагрузка. **Решение:** Включили priority inheritance в VxWorks, загрузили патч через радио с Земли (за 300 млн км!).
**Priority Inheritance Protocol (PIP)** - решение priority inversion. Когда высокоприоритетная задача блокируется на mutex, владелец mutex временно наследует её приоритет. После unlock приоритет возвращается.
**Решения Priority Inversion:** 1. **Priority Inheritance:** владелец mutex наследует приоритет заблокированной задачи 2. **Priority Ceiling Protocol:** mutex имеет "потолок" приоритета. Владелец получает этот приоритет при захвате 3. **Lock-Free алгоритмы:** избегаем mutex через atomic операции (но сложнее в реализации)
**Priority Ceiling Protocol (PCP)** - более агрессивный подход. Каждому mutex назначается ceiling priority (максимальный приоритет задач, использующих mutex). Задача может захватить mutex только если её приоритет выше ceiling всех уже захваченных mutex в системе.
Когда Priority Inversion НЕ проблема
В non-RT системах (Linux desktop, Windows) priority inversion допустим. Scheduler использует dynamic priorities, fair scheduling (CFS в Linux). Краткосрочная блокировка не критична. Но в RT системах даже 1мс задержки может нарушить deadline. Поэтому все RT OS (VxWorks, QNX, FreeRTOS, PREEMPT_RT Linux) реализуют priority inheritance по умолчанию для mutex.
Как Priority Inheritance Protocol решает проблему инверсии приоритетов?
PREEMPT_RT Linux
**PREEMPT_RT (Real-Time preemption patch)** - набор патчей, превращающих стандартный Linux в Hard Real-Time систему. Цель: сделать ядро полностью вытесняемым (preemptable), убрать unbounded latency источники.
Обычный Linux - General-Purpose OS. Scheduler оптимизирует throughput и fairness, но не гарантирует latency. Например, spin_lock в ядре отключает preemption на непредсказуемое время. Обработчики прерываний (IRQ) блокируют систему.
**Ключевые изменения PREEMPT_RT:** 1. **Spinlocks → rt_mutex:** В vanilla Linux spin_lock крутится в цикле, отключая preemption. В RT заменяется на sleeping mutex с priority inheritance. 2. **Threaded IRQ:** Обработчики прерываний выполняются в kernel threads (потоки ядра) с приоритетом. Можно вытеснить IRQ handler более важной RT задачей. 3. **High-resolution timers:** Точность до microseconds вместо jiffies (обычно 1-10ms).
**Уровни preemption в Linux:** - **PREEMPT_NONE:** No forced preemption (server) - **PREEMPT_VOLUNTARY:** Voluntary preemption (desktop) - **PREEMPT:** Preemptible kernel (low-latency desktop) - **PREEMPT_RT:** Full real-time preemption (hard RT) Настраивается при компиляции ядра через `make menuconfig`.
PREEMPT_RT в automotive (Tesla, Waymo)
Автомобили используют Linux с PREEMPT_RT для: - **ADAS (Advanced Driver Assistance):** Обработка camera/lidar данных в реальном времени. Deadline: <10ms от захвата кадра до решения. - **CAN bus communication:** Отправка команд ECU (engine control units) с гарантированной latency. - **Infotainment + safety:** Одна OS для мультимедиа (soft RT) и safety-critical систем (hard RT) через cgroups изоляцию. Пример: **Automotive Grade Linux (AGL)** - дистрибутив на базе PREEMPT_RT для автопрома.
**Ограничения PREEMPT_RT:** - **Throughput vs Latency trade-off:** RT оптимизирует worst-case, жертвуя average-case пропускной способностью. Для серверов с тысячами подключений это минус. - **Драйверы:** Не все драйверы совместимы с RT. Проприетарные драйверы (Nvidia) часто отключают preemption. - **Сложность отладки:** Timing bugs проявляются только под нагрузкой, воспроизвести сложно.
Почему в PREEMPT_RT Linux обработчики прерываний (IRQ) выполняются в kernel threads?
Анализ latency и worst-case
**Latency analysis** - критический этап разработки RT систем. Недостаточно просто измерить среднюю задержку - нужно математически доказать, что worst-case execution time (WCET) укладывается в deadline.
Источники latency в системе: 1. **Interrupt latency:** Время от прерывания до начала обработчика 2. **Preemption latency:** Время от запроса вытеснения до context switch 3. **Scheduling latency:** Время от пробуждения до получения CPU 4. **Critical section latency:** Время блокировки на locks
**Stress testing для worst-case:** Недостаточно измерить latency на idle системе. Нужна нагрузка: - **CPU stress:** `stress-ng --cpu 8` - загрузить все ядра - **Memory stress:** `stress-ng --vm 4 --vm-bytes 1G` - page faults, cache misses - **Disk I/O:** `dd if=/dev/zero of=/tmp/test bs=1M count=1024` - DMA, interrupts - **Network:** `iperf3 -c server` - сетевые прерывания
**WCET (Worst-Case Execution Time) analysis:** Для safety-critical систем (авиация, медицина) нужен **статический анализ WCET** - математическое доказательство верхней границы времени выполнения. Инструменты: - **aiT WCET Analyzer:** Static analysis на уровне машинного кода - **RapiTime:** Hybrid analysis (статика + трассировка) - **Bound-T:** Open-source WCET для embedded Требуется для сертификации (DO-178C для авиации, IEC 61508 для промышленности).
Automotive: ISO 26262 и latency requirements
Стандарт ISO 26262 (functional safety для автомобилей) определяет ASIL уровни (Automotive Safety Integrity Level): - **ASIL D** (критично): Airbag, steering, brakes → deadline <10ms, WCET должен быть доказан - **ASIL B** (важно): ABS, ESC → deadline <50ms - **QM** (некритично): Infotainment → best-effort Для ASIL D требуется: 1. Static WCET analysis 2. Формальная верификация (model checking) 3. Redundant execution + voting 4. Extensive testing (millions of test cases)
**Deadline Miss handling:** Что делать если RT задача не уложилась в deadline? 1. **Logging:** Записать событие для анализа (через lock-free ring buffer) 2. **Degradation:** Перейти в safe mode (например, автомобиль замедляется) 3. **Failover:** Переключиться на резервную систему 4. **Panic:** Для Hard RT (airbag) лучше crash чем неверное решение
Real-Time система - это просто очень быстрая система. Нужно использовать самое быстрое железо и оптимизировать код
Real-Time - это про предсказуемость (determinism), а не скорость. Медленная но детерминированная система лучше быстрой непредсказуемой
RTOS может работать на медленном микроконтроллере (ARM Cortex-M @ 48MHz) и быть Hard RT. А суперкомпьютер на Linux без PREEMPT_RT не даст RT гарантий. Ключ - bounded latency: WCET должен быть математически доказан. Это достигается архитектурой (priority inheritance, preemptable kernel, lock-free алгоритмы), а не GHz процессора. Mars Pathfinder крашился не из-за медленного CPU, а из-за priority inversion - архитектурной проблемы. Суть RT: лучше выполнить за 10мс ВСЕГДА, чем за 1мс в среднем но иногда за 1000мс.
Ключевые идеи
- **RT ≠ Fast. RT = Deterministic.** RTOS гарантирует worst-case latency, а не average. Медленная RTOS на микроконтроллере надёжнее суперкомпьютера без RT.
- **Priority Inversion - убийца RT систем.** High priority задача блокируется через shared resource. Решение: Priority Inheritance Protocol (владелец mutex наследует приоритет заблокированной задачи).
- **PREEMPT_RT превращает Linux в Hard RT.** Spinlocks → rt_mutex, IRQ → threads, priority inheritance везде. Latency <100μs вместо milliseconds.
- **WCET analysis критичен для safety.** Для авиации/медицины нужно математически доказать верхнюю границу времени выполнения. Static analysis + stress testing под нагрузкой.
Связанные темы
Real-Time системы строятся на фундаменте OS планирования и синхронизации:
- CPU Scheduling — RT планировщики (SCHED_FIFO, RMS, EDF) vs general-purpose (CFS). Priority-based preemptive scheduling как основа RT
- Синхронизация и locks — Priority inheritance для mutex. Проблема priority inversion решается на уровне примитивов синхронизации
- Deadlocks — В RT системах deadlock особенно опасен - приводит к deadline miss. Priority Ceiling Protocol предотвращает deadlocks
- Linux internals — PREEMPT_RT патчи меняют ядро Linux: threaded IRQ, rt_mutex, high-resolution timers. Глубокое понимание kernel internals
Вопросы для размышления
- Почему Mars Pathfinder использовал VxWorks RTOS вместо обычного Linux? Какие требования для космических миссий делают RT критичным?
- Autonomous vehicle: camera захватила пешехода. Как распределить RT приоритеты между задачами: object detection, path planning, brake control?
- Trade-off: PREEMPT_RT даёт bounded latency но снижает throughput на ~10-15%. Когда это приемлемо, а когда нет? Сравни web-сервер vs industrial robot.