No meu ambiente (Ubuntu 25.04, KDE Plasma 6, X11), percebi que o painel e os widgets travavam durante compilações pesadas ou processos do FFmpeg, enquanto as janelas propriamente continuavam fluindo normalmente
Por exemplo, o navegador, o terminal, trabalhavam sem oscilação, porém os componentes de painel e widgets paravam de responder consideravelmente.
1. Fundamentos do Scheduling no Unix
O Unix clássico (System V, BSD) implementava um agendador simples e cooperativo, baseado em prioridades fixas. Cada processo tinha um valor de nice (de −20 a +19), e o sistema concedia um quantum de tempo (geralmente 10 ms) a cada processo conforme sua prioridade.
Quando todos tinham prioridade igual, o sistema fazia round-robin.
Não havia preempção dentro do kernel nem consciência de I/O ou GPU — apenas tempo de CPU.
Podemos dizer que o scheduling do Unix original e o das primeiras versões do Windows (3.x, 95, 98, ME) compartilham a mesma filosofia cooperativa, porém com mecanismos diferentes de controle e preempção.
O scheduling do Unix clássico
No Unix original (anos 70–80, System V, BSD 4.x):
- O sistema era multitarefa cooperativa com prioridades, depois evoluindo para preemptiva com “time slices”.
- Cada processo possuía uma prioridade estática e dinâmica, ajustada com base no uso de CPU e I/O.
- O kernel fazia um round-robin dentro de cada faixa de prioridade.
- O processo rodava até: esgotar seu quantum de tempo, bloquear em I/O, ou voluntariamente ceder CPU (via sleep() ou wait()).
Ou seja: o sistema confiava que os processos “se comportariam”, devolvendo o controle ao kernel quando terminassem sua parte.
Windows 3.x: multitarefa cooperativa pura
O Windows 3.1 e 3.11 rodavam sobre o MS-DOS, que era single-tasking. O Windows criou um ambiente multitarefa cooperativo — mas só entre aplicações Windows. Programas DOS ainda rodavam de forma exclusiva.
- Cada aplicativo tinha o controle total da CPU até chamar GetMessage() ou funções do GDI/User.
- O sistema de janelas dependia de cada app para “renderizar e devolver o tempo”.
- Se um app travasse ou entrasse em loop, todo o sistema congelava.
- Não havia preempção de kernel nem prioridades reais.
Isso é análogo ao Unix cooperativo inicial: o agendador confiava que cada processo cederia o CPU voluntariamente.
Esse modelo em UNIX primordial funcionava bem em ambientes de terminal, mas não se adaptava ao multitarefa moderna, com threads, aceleração gráfica e composição de janelas.
Windows 95 / 98 / ME: híbrido cooperativo + preemptivo
Com o Windows 95, a Microsoft introduziu um kernel 32 bits híbrido:
- Aplicações 32-bit (Win32) eram preemptivamente agendadas.
- Aplicações 16-bit (legado do Windows 3.x) continuavam cooperativas.
- O sistema inteiro ainda rodava em um único espaço de endereçamento compartilhado (sem proteção de memória total).
- O agendador usava quantum curtos (~20 ms) e prioridades fixas para threads.
Resultado: se um aplicativo 16-bit não cedia o controle, ele podia travar as janelas 32-bit também — assim como um processo mal-comportado no Unix cooperativo podia travar o terminal todo.
o scheduling do Unix original é análogo ao das versões iniciais do Windows, especialmente Windows 3.x, e parcialmente ao modelo híbrido de Windows 95/98/ME.
Todos partilhavam a mesma limitação fundamental:
O sistema dependia da boa vontade dos processos em “ceder o tempo”.
Somente com o advento do Unix preemptivo moderno e do Windows NT é que os dois mundos convergiram para o paradigma que usamos hoje — onde o kernel decide, não o processo.
2. Evolução: Linux CFS (Completely Fair Scheduler)
O CFS, introduzido no kernel 2.6.23, é preemptivo e orientado a justiça. Ele organiza as threads em uma árvore RB-tree por CPU, garantindo tempo proporcional ao peso de cada processo.
- nice = 0 → tempo normal
- nice = 10 → ~40 % do tempo de CPU
- nice = −10 → ~250 % mais prioridade
Há também políticas real-time (SCHED_FIFO, SCHED_RR) usadas por áudio, KWin e interrupções, e o SCHED_DEADLINE para latências garantidas.
O CFS, porém, enxerga apenas CPU. Ele não entende esperas em GPU, poll() de drivers ou bloqueios de renderização. Eis o pulo do gato, ou melhor, o gato não pula de lá pra cá.
3. O Starvation que observei no X11 (Plasma 6 + Intel Iris Xe)
Investigando, descobri que o plasmashell usa QtQuick + OpenGL (GLX), e a Intel Iris Xe trabalha com o driver Mesa iris_dri.so, que processa comandos GL em thread pool no userspace.
O que acontecia:
- Ao iniciar um make -j8 ou um FFmpeg pesado, todas as CPUs iam a 100 %.
- O kernel CFS distribuía CPU igualmente (todos os processos com nice = 0).
- O plasmashell ficava aguardando o loop QtQuick renderizar via GLX.
- As threads GLX disputavam as mesmas filas que as de FFmpeg.
- Chamadas como poll() e drmWaitVBlank() ficavam sem fatia de CPU.
- O painel travava, mas o compositor (kwin_x11) seguia normal, pois roda com prioridade RT.
Em resumo: as threads de renderização do painel sofriam starvation de CPU e GPU, enquanto o compositor seguia ativo.
4. Por que o Wayland resolve isso
No Wayland, cada app possui seu próprio EGL surface e canal de comunicação direta com o compositor (via DMA-BUF). Não existe servidor X central nem contexto GLX compartilhado.
Com isso, mesmo que o FFmpeg consuma todos os cores, o compositor Wayland mantém prioridade RT e cada processo continua fluindo de forma independente. O painel não depende mais de GLX nem do X Server — e simplesmente não trava.
5. Relação com o Unix tradicional
O Unix original tratava o display como um recurso monolítico (um servidor X único). O Linux herdou esse modelo, mas o Wayland rompe essa herança e distribui a responsabilidade: entrada, composição e exibição são processos distintos, comunicando-se de forma assíncrona. É como se a garatuja agora fosse um restaurante, onde temos o garçom, a cozinha e os clientes famintos. 🙂
É, na prática, o retorno ao princípio “faça uma coisa e faça bem”, agora aplicado à pilha gráfica.
6. Scheduling no Plasma 6 (na prática)
Componente | Política / Prioridade | Efeito
————————-|—————————|——————————————–
kwin_x11 / kwin_wayland | SCHED_RR (tempo real) | CPU para compor frames
plasmashell | SCHED_OTHER (nice = 0) | Sujeito a starvation no X11
ffmpeg / gcc / make | SCHED_OTHER (nice = 0) | Competem com o painel
PipeWire / PulseAudio | SCHED_RR (tempo real) | Latência garantida
No X11, o plasmashell compartilha contexto GL com outros processos. No Wayland, cada um tem seu contexto e frame loop próprio — isolamento real.
7. Prós e contras da migração para o Wayland
Aspecto | X11 (GLX) | Wayland (EGL / GBM)
—————————–|————————————|———————————————
Modelo de processos | Centralizado (X Server único) | Descentralizado (cada app é um surface)
Gerenciamento de CPU/GPU | Contexto GLX compartilhado | Contextos isolados por app
Starvation sob carga | Frequente | Virtualmente inexistente
V-Sync / tearing | Depende do driver | Sincronizado por design
Compatibilidade | Total (legado) | XWayland (leve overhead)
Ferramentas de automação | xdotool, xrandr, xinput | ydotool, wlr-randr, libinput debug
Segurança | Apps podem acessar janelas alheias| Isolamento completo
Eficiência energética (Intel)| Menor | Maior
Suporte futuro | Manutenção | Desenvolvimento ativo
8. Visualizando o comportamento
No X11:
FFmpeg → CPU 100 %
↓
GLX context lock (iris_dri.so)
↓
poll() bloqueia
↓
plasmashell 0 % CPU
↓
painel travado, kwin ok No Wayland:
FFmpeg → CPU 100 %
↓
Wayland compositor (RT)
↓
plasmashell em surface EGL
↓
painel redesenha normalmente 9. Conclusão
Essa análise me mostrou de forma clara como o comportamento do scheduler e a arquitetura gráfica se entrelaçam:
- Unix: agendador cooperativo e display monolítico.
- Linux + X11: preempção justa, mas servidor global suscetível a starvation.
- Wayland: isolamento completo e sincronização moderna via EGL.
Migrar para o Wayland me trouxe estabilidade, fluidez e isolamento real das cargas de CPU/GPU, especialmente com hardware Intel Iris Xe. O agendador continua o mesmo — mas agora, a pilha gráfica trabalha com ele, e não contra ele.
<3 “O Wayland não é apenas o sucessor do X — é a reconciliação entre o kernel e o compositor.”
Diversas vezes critiquei o wayland não pelo seu design mas por lack of features. Eu acho que os benefícios em estabilidade e até mesmo segurança, compensam muito o deficit em algumas áreas que sequer são tão utilizadas; acho digno que se mova em frente quanto a implementar essas lacunas do que manter-se arraigado num conceito antiquado, num paradigma que funciona bem mas apresenta vulnerabilidades e falhas devido a sua concepção estrutural.
Basta que as distros mantenham ambos a la carte e c1est la vie. Keep moving forward.