Featured image of post Por que 'rápido' não é suficiente: Sistemas Operacionais de Tempo Real (RTOS), WCET, escalonamento RMS vs. EDF e a inversão de prioridade da Mars Pathfinder

Por que 'rápido' não é suficiente: Sistemas Operacionais de Tempo Real (RTOS), WCET, escalonamento RMS vs. EDF e a inversão de prioridade da Mars Pathfinder

Por que o PC gamer mais rápido não pode pilotar um avião comercial? Uma análise matemática completa sobre RTOS, funções de utilidade temporal (Hard/Firm/Soft), tempo de execução no pior caso (WCET), teoremas de Liu & Layland (1973) para RMS (ln 2 ≈ 69,3%) e EDF (100%), e o incidente da Mars Pathfinder da NASA (1997) resolvido via protocolos de herança e teto de prioridade (PIP/PCP).

1. O abismo fundamental entre “rápido” e “tempo real”

Na linguagem cotidiana, “processamento em tempo real” é frequentemente confundido com “execução ultrarrápida”. Contudo, nem mesmo um servidor com processador superescalar multicore de vários gigahertz, capaz de responder consultas em média em um milissegundo, jamais poderia controlar o sistema Fly-by-Wire de um avião comercial, o acionamento de um airbag automotivo ou um marca-passo cardíaco. Por quê? Porque sistemas de propósito geral otimizam a vazão média (Average Throughput): se um cálculo leva \(0,5\,\text{ms}\) em \(99,999\,\%\) das vezes, mas uma vez em um milhão atrasa \(200\,\text{ms}\) devido a um cache miss, page fault ou pausa do Garbage Collector (GC), o avião perde sustentação ou o airbag explode após a colisão.

Segundo a formulação clássica de Donald Gillies e Hermann Kopetz, o axioma da computação em tempo real estabelece que a corretude de um sistema depende não apenas da exatidão lógica e aritmética do resultado, mas também do instante físico \(t\) em que ele é entregue em relação ao seu prazo final (deadline \(d_i\)). Pela função de utilidade temporal \(U(t)\), distinguem-se três classes:

\[U_{\text{hard}}(t) = \begin{cases} V & (t \le d) \\ -\infty & (t > d) \end{cases}, \qquad U_{\text{firm}}(t) = \begin{cases} V & (t \le d) \\ 0 & (t > d) \end{cases}, \qquad U_{\text{soft}}(t) = \begin{cases} V & (t \le d) \\ V e^{-\alpha(t-d)} & (t > d) \end{cases}\]
  • Tempo real rígido (Hard Real-Time): Perder um único prazo (\(t > d\)) causa falha catastrófica (\(U = -\infty\), ex.: controle de voo, freios ABS). Exige prova matemática estática offline.
  • Tempo real firme (Firm Real-Time): Um resultado atrasado tem valor zero (\(U = 0\)) e é descartado imediatamente (ex.: inspeção visual em esteira de alta velocidade, cancelamento de ordens em HFT).
  • Tempo real brando (Soft Real-Time): A utilidade decai continuamente após \(d\) (ex.: streaming de vídeo a 60 fps, chamadas VoIP).
Dimensão arquiteturalSO de propósito geral (GPOS: Linux / Windows / macOS)SO de tempo real (RTOS: VxWorks / QNX / FreeRTOS / seL4)
Objetivo de otimizaçãoMaximizar vazão média e justiça (CFS / EEVDF)Garantir determinismo temporal e limitar o pior tempo de resposta (WCRT)
Latência de interrupçãoMicrossegundos a dezenas de milissegundos (cauda longa estocástica)Centenas de nanossegundos a poucos microssegundos (limite constante \(O(1)\))
Preemptibilidade do kernelKernels monolíticos com seções críticas não preemptivasKernel totalmente preemptivo ou microkernel mínimo (QNX, seL4)
Memória e hardwareMemória virtual paginada, malloc, GC, máxima execução especulativaPartições estáticas, pools \(O(1)\), SRAM acoplada (TCM) e travamento de cache

2. O pesadelo do tempo de execução no pior caso (WCET)

Toda teoria de escalonamento em tempo real pressupõe conhecer previamente o tempo de execução no pior caso (Worst-Case Execution Time, \(C_i\)) de cada tarefa \(\tau_i\). Aqui reside um profundo paradoxo da arquitetura de computadores: quase todos os mecanismos de hardware criados para acelerar a velocidade média de uma CPU (caches L1/L2/L3, predição de desvio, execução fora de ordem OoO, TLB, DVFS e interrupções de gerenciamento do sistema SMI não mascaráveis) destroem a previsibilidade do WCET.

Em pipelines Out-of-Order com caches ocorrem inclusive anomalias temporais (Timing Anomalies): um acerto local de cache (Cache Hit) pode permitir que um caminho especulativo ocupe antes um barramento compartilhado, tornando o tempo total de execução do programa maior do que se tivesse ocorrido um erro de cache (Cache Miss)! Por isso, sistemas críticos (DO-178C Nível A, ISO 26262 ASIL-D) utilizam memória Scratchpad SRAM / TCM determinística e travamento de cache (Cache Locking), calculando estaticamente o limite superior do WCET via interpretação abstrata e a técnica de enumeração implícita de caminhos (IPET) como um problema de programação linear inteira (ILP) sobre o grafo de fluxo de controle (CFG):

\[\text{WCET} = \max \sum_{i=1}^{N} c_i x_i \quad \text{sujeito a} \quad \sum_{j} d_{j \to i} = x_i = \sum_{k} d_{i \to k} \quad (\text{conservação de fluxo e limites de laço})\]

3. Liu & Layland (1973): Escalonamento periódico (RMS vs. EDF)

Seja um conjunto de \(n\) tarefas periódicas independentes \(\Gamma = \{\tau_1, \dots, \tau_n\}\) com \(\tau_i = (C_i, T_i, D_i)\) (WCET \(C_i\), período \(T_i\), prazo implícito \(D_i = T_i\)). A utilização total do processador é:

\[U = \sum_{i=1}^{n} \frac{C_i}{T_i}\]

Em 1973, C. L. Liu e James W. Layland demonstraram os teoremas fundamentais que regem prioridades estáticas e dinâmicas:

3.1 Escalonamento Monotônico em Taxa (RMS) e o limite \(\ln 2 \approx 69,3\,\%\)

No escalonamento preemptivo de prioridade fixa, a regra Rate Monotonic (RMS) atribui prioridades estáticas em ordem inversa ao período: quanto menor o período \(T_i\) (maior a frequência \(1/T_i\)), maior a prioridade estática. Liu & Layland provaram o teorema do instante crítico (o pior tempo de resposta de \(\tau_i\) ocorre quando ela é liberada simultaneamente com todas as tarefas de maior prioridade em \(t=0\)) e a otimalidade do RMS entre todos os algoritmos de prioridade fixa, com o menor limite superior de utilização:

\[U = \sum_{i=1}^{n} \frac{C_i}{T_i} \le U_{\text{lub}}(n) = n\left(2^{1/n} - 1\right) \xrightarrow{n \to \infty} \ln 2 \approx 0,6931 \quad (69,3\,\%)\]

Importante: \(69,3\,\%\) é apenas uma condição suficiente, não necessária! Se os períodos forem harmônicos (cada período é múltiplo inteiro dos menores, ex.: \(5\,\text{ms}, 10\,\text{ms}, 20\,\text{ms}\)), o RMS atinge 100% de utilização. Para conjuntos gerais, a análise de tempo de resposta (RTA) de Joseph & Pandya (1986) fornece uma condição necessária e suficiente exata por iteração de ponto fixo (\(R_i \le D_i\)):

\[R_i^{(k+1)} = C_i + \sum_{j \in hp(i)} \left\lceil \frac{R_i^{(k)}}{T_j} \right\rceil C_j\]

3.2 Primeiro o Prazo Mais Cedo (EDF) e a otimalidade de \(100\,\%\)

No escalonamento preemptivo de prioridade dinâmica, o Earliest Deadline First (EDF) concede a cada instante a prioridade máxima ao trabalho pronto cujo prazo absoluto \(d_{i,k} = r_{i,k} + D_i\) esteja mais próximo. Em um monoprocessador, a condição necessária e suficiente de escalonabilidade sob EDF atinge o limite físico:

\[U = \sum_{i=1}^{n} \frac{C_i}{T_i} \le 1,00 \quad (100\,\%)\]

Exemplo: Com \(\tau_1 = (C_1=2, T_1=5)\) e \(\tau_2 = (C_2=4, T_2=7)\), a utilização é \(U = 97,14\,\%\). Sob RMS, a chegada de \(\tau_{1,2}\) em \(t=5\) (\(d=10\)) interrompe cegamente \(\tau_{2,1}\) (\(d=7\), faltando apenas \(1\,\text{ms}\)), causando \(R_2 = 8 > 7\) (perda de prazo!). Sob EDF, em \(t=5\), como \(d_{2,1}=7 < d_{1,2}=10\), o EDF impede a preempção e \(\tau_{2,1}\) termina a tempo em \(t=6 \le 7\).

Ainda assim, a indústria (VxWorks, FreeRTOS, QNX, AUTOSAR) prefere RMS/DMS porque, sob sobrecarga transitória (\(U > 1,0\)), o EDF sofre um efeito dominó catastrófico onde uma tarefa atrasada monopoliza a CPU e faz todas as seguintes falharem em cadeia, enquanto o RMS protege \(100\,\%\) as tarefas críticas de alta prioridade e é implementado em \(O(1)\) com bitmap e instrução CLZ.

Critério de comparaçãoRate Monotonic (RMS: Prioridade fixa)Earliest Deadline First (EDF: Prioridade dinâmica)
Atribuição de prioridadeEstática: menor período \(T_i \implies\) maior prioridadeDinâmica: prazo absoluto \(d_{i,k}\) mais próximo \(\implies\) maior prioridade
Limite de utilizaçãoSuficiente: \(n(2^{1/n}-1) \to 69,3\,\%\) (\(100\,\%\) em períodos harmônicos)Necessária e suficiente: sempre \(100\,\%\) (\(\sum C_i/T_i \le 1\))
Complexidade no kernel\(O(1)\) (bitmap de prioridades + instrução CLZ)\(O(\log n)\) (heap mínimo ou árvore rubro-negra dinâmica)
Comportamento em sobrecarga (\(U > 1\))Degradação graciosa: tarefas de alta prioridade sobrevivem sempreEfeito dominó catastrófico: falha em cascata de todas as tarefas

4. O incidente da Mars Pathfinder da NASA (1997) e a inversão de prioridade

Em julho de 1997, após pousar em Marte, a sonda Mars Pathfinder da NASA (CPU IBM RAD6000 rodando o RTOS VxWorks) começou a sofrer reinicializações completas forçadas pelo seu watchdog, perdendo dias inteiros de dados científicos.

A causa foi uma inversão de prioridade ilimitada (Unbounded Priority Inversion) entre três tarefas disputando um mutex \(M\) que protegia o “barramento de informações” compartilhado:

  • A tarefa meteorológica de baixa prioridade \(\tau_L\) (ASI/MET) trava o mutex \(M\);
  • A tarefa crítica de distribuição do barramento de alta prioridade \(\tau_H\) (bc_dist) acorda, solicita \(M\) e fica bloqueada;
  • Antes que \(\tau_L\) libere \(M\), chegam tarefas de comunicação de prioridade média \(\tau_M\) (que não usam \(M\)!). Como \(\text{Priority}(\tau_M) > \text{Priority}(\tau_L)\), \(\tau_M\) interrompe \(\tau_L\) por longo tempo, impedindo que \(\tau_L\) destrave \(M\) e mantendo \(\tau_H\) bloqueada até o watchdog reiniciar a espaçonave.
  flowchart TD
    subgraph Bug["Inversão de prioridade ilimitada na Mars Pathfinder (1997)"]
        B1["1. Tarefa de baixa prioridade τ_L trava o mutex M"] --> B2["2. Tarefa de alta prioridade τ_H solicita M e entra em estado BLOQUEADO"]
        B2 --> B3["3. Chega a tarefa de prioridade média τ_M (que não usa M)!<br/>Como Priority(τ_M) > Priority(τ_L), τ_M interrompe τ_L e monopoliza a CPU"]
        B3 --> B4["4. τ_L não consegue liberar M -> τ_H fica bloqueada indefinidamente<br/>O watchdog expira e força o reset completo da sonda em Marte!"]
    end
  flowchart TD
    subgraph Fix["Protocolos de sincronização de Sha, Rajkumar & Lehoczky (1990)"]
        F1["Solução A: Protocolo de Herança de Prioridade (PIP)<br/>Ao bloquear τ_H em M, o kernel eleva a prioridade efetiva de τ_L<br/>ao nível de τ_H! τ_M não pode interromper e τ_L libera M imediatamente"]
        F2["Solução B: Protocolo de Teto de Prioridade Imediato (ICPP)<br/>Cada mutex M recebe um teto Ceil(M) = maior prioridade de seus usuários.<br/>Elevação imediata ao travar: zero deadlock e no máximo 1 bloqueio (B_i)!"]
        F1 --> F2
    end

A solução matemática foi provada por Sha, Rajkumar e Lehoczky em 1990:

  1. Protocolo de Herança de Prioridade (PIP: Priority Inheritance Protocol): Quando \(\tau_H\) bloqueia em um mutex \(M\) mantido por \(\tau_L\), o kernel eleva temporariamente a prioridade efetiva de \(\tau_L\) ao nível de \(\tau_H\), impedindo que \(\tau_M\) interrompa. Após reproduzir o bug na Terra, os engenheiros do JPL enviaram a 190 milhões de quilômetros um comando C ao shell do VxWorks alterando na RAM a variável global SEM_INVERSION_SAFE de 0 para 1, salvando a missão!
  2. Protocolo de Teto de Prioridade (PCP / ICPP: Immediate Priority Ceiling Protocol): Como o PIP ainda permite bloqueio encadeado e deadlock, o ICPP (padrão em POSIX PTHREAD_PRIO_PROTECT e AUTOSAR OS) atribui a cada mutex \(M_k\) um teto estático \(\text{Ceil}(M_k) = \max\{\text{Priority}(\tau_i) \mid \tau_i \text{ usa } M_k\}\) e eleva a prioridade de qualquer tarefa no exato instante em que ela adquire \(M_k\). Isso garante ausência total de deadlocks e limita o bloqueio máximo de qualquer tarefa a no máximo uma única seção crítica (\(B_i\)):
\[R_i^{(k+1)} = C_i + B_i + \sum_{j \in hp(i)} \left\lceil \frac{R_i^{(k)}}{T_j} \right\rceil C_j\]
comments powered by Disqus