Sistemas de Tempo Real com Zig

Sistemas de Tempo Real com Zig

Sistemas de tempo real exigem respostas dentro de prazos rigorosos — um atraso de milissegundos pode significar falha catastrófica. Zig, sem garbage collector, sem exceções escondidas e com controle total de alocações, é naturalmente adequado para este domínio.

Por Que Zig para Real-Time

Requisito Real-TimeZigGoJavaC
Sem GC pausesSimNaoNaoSim
Latência determinísticaSimNaoNaoSim
Controle de alocaçõesTotalParcialNaoTotal
Segurança de memóriaSim*SimSimNao
Sem exceções escondidasSimParcialNaoSim

*Em modo Debug/ReleaseSafe

Pool de Memória Pré-Alocado

Em sistemas real-time, alocações dinâmicas durante operação são proibidas:

fn PoolFixo(comptime T: type, comptime N: usize) type {
    return struct {
        items: [N]T = undefined,
        livre: [N]bool = [_]bool{true} ** N,

        const Self = @This();

        pub fn alocar(self: *Self) ?*T {
            for (&self.livre, 0..) |*l, i| {
                if (l.*) {
                    l.* = false;
                    return &self.items[i];
                }
            }
            return null; // Pool esgotado — sem panic, sem alocação
        }

        pub fn liberar(self: *Self, ptr: *T) void {
            const idx = (@intFromPtr(ptr) - @intFromPtr(&self.items)) / @sizeOf(T);
            self.livre[idx] = true;
        }
    };
}

const Tarefa = struct {
    id: u32,
    prioridade: u8,
    deadline_us: u64,
    funcao: *const fn () void,
};

// Pool pré-alocado de 256 tarefas — zero alocações em runtime
var pool_tarefas = PoolFixo(Tarefa, 256){};

Scheduler de Tempo Real

const Scheduler = struct {
    tarefas: [64]*Tarefa = undefined,
    num_tarefas: usize = 0,

    /// Adicionar tarefa com deadline — O(n) insertion sort por prioridade
    pub fn agendar(self: *Scheduler, tarefa: *Tarefa) void {
        var pos = self.num_tarefas;
        while (pos > 0 and self.tarefas[pos - 1].prioridade < tarefa.prioridade) : (pos -= 1) {
            self.tarefas[pos] = self.tarefas[pos - 1];
        }
        self.tarefas[pos] = tarefa;
        self.num_tarefas += 1;
    }

    /// Executar próxima tarefa de maior prioridade
    pub fn executar(self: *Scheduler) void {
        if (self.num_tarefas == 0) return;

        const tarefa = self.tarefas[0];
        // Verificar deadline
        const agora = getTimestampUs();
        if (agora > tarefa.deadline_us) {
            // DEADLINE MISS — ação de contingência
            handleDeadlineMiss(tarefa);
            return;
        }

        tarefa.funcao();

        // Remover tarefa executada
        self.num_tarefas -= 1;
        for (0..self.num_tarefas) |i| {
            self.tarefas[i] = self.tarefas[i + 1];
        }
    }
};

Conclusão

Zig é uma alternativa moderna e mais segura ao C para sistemas de tempo real. A ausência de garbage collector, o controle explícito de alocações e a previsibilidade de performance fazem de Zig uma escolha natural para aplicações onde deadlines são inegociáveis.

Se você busca alternativas para sistemas de tempo real, confira também como Rust se posiciona nesse domínio, oferecendo garantias de segurança de memória em tempo de compilação sem custos de runtime.

Conteúdo Relacionado

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.