<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>OSDev | FoxTechWorld</title><link>https://foxtechworld.github.io/categories/osdev/</link><description>Conteúdo recente em OSDev no FoxTechWorld.</description><language>pt-BR</language><copyright>KitsuneSemCalda (CC BY 4.0)</copyright><lastBuildDate>Sat, 15 Aug 2026 00:00:00 -0300</lastBuildDate><generator>Hugo</generator><atom:link href="https://foxtechworld.github.io/categories/osdev/" rel="self" type="application/rss+xml"/><item><title>OSDev: pervasive multithreading, SMT e escalonamento</title><link>https://foxtechworld.github.io/osdev-o-multithread-perdido-pervasive-multithread/</link><guid isPermaLink="true">https://foxtechworld.github.io/osdev-o-multithread-perdido-pervasive-multithread/</guid><pubDate>Fri, 28 Nov 2025 12:31:28 -0300</pubDate><description>Uma análise de pervasive multithreading, SMT e topologia de CPU, com uma proposta de escalonamento consciente para o FKernel.</description><category>Programação</category><category>OSDev</category><category>Programação</category><category>Sistemas Operacionais</category><category>OSDev</category><category>C++</category><category>Haiku</category><category>BeOS</category><category>SMT</category><category>Escalonamento</category><content:encoded><![CDATA[<p>Quando olhamos a história dos sistemas operacionais vemos muitas ideias promissoras nascerem, ganharem nichos e, às vezes, sumirem sem deixar rastro. Entre esses projetos, o BeOS — e seu sucessor Haiku — se destacam por uma opção arquitetural clara: priorizar interatividade e baixa latência por meio do que se chamou de Pervasive Multithread.</p>
<h2 id="o-diferencial-do-beos--haiku">O diferencial do BeOS / Haiku</h2>
<p>O ponto central é simples: escalonar no nível da thread, com threads muito leves e políticas que favorecem responsividade em vez de throughput máximo. Isso reduz a sobrecarga de contexto ao trocar entre threads da mesma aplicação e permite uma taxa alta de comutação sem penalizar a interatividade.</p>
<p>Essa ênfase na responsividade ajuda a explicar decisões de projeto aparentemente simples — por exemplo, por que tratar a unidade de escalonamento como a thread em vez do processo — e prepara o terreno para entendermos o conceito que vem a seguir.</p>
<h2 id="o-que-é-pervasive-multithread">O que é Pervasive Multithread</h2>
<p>Pervasive Multithread é um modelo composto — kernel e runtime cooperam — em que o sistema trata a concorrência como algo onipresente: o scheduler opera por thread, há prioridades finas (tipicamente 0–120) e políticas que privilegiam latência e previsibilidade sobre o rendimento bruto.</p>
<p>O resultado prático é que a aplicação vê threads leves com prioridades ajustáveis, e o kernel faz o mínimo necessário ao salvar/restaurar contexto, mantendo a máquina responsiva para cargas interativas.</p>
<p>Com essa definição em mente, vale contrastar como o hardware moderno tenta aumentar paralelismo com técnicas como SMT — e por que essa camada física pode confundir as decisões de escalonamento quando não é considerada explicitamente.</p>
<h2 id="por-que-smt-não-é-um-cpu--explicação-técnica">Por que SMT não é um “CPU” — explicação técnica</h2>
<p>Simultaneous multithreading (SMT) cria múltiplas hardware threads dentro do mesmo núcleo físico. Essas hardware threads compartilham pipelines, unidades funcionais, níveis de cache e o mesmo domínio energético. Em particular:</p>
<ul>
<li>Compartilhamento de execution units: duas hardware threads podem disputar as mesmas ALUs, FPU e portas de memória.</li>
<li>Contenção em caches: L1 e, em muitos designs, partes do L2/L3 são compartilhadas ou têm efeitos de conflito entre threads.</li>
<li>Dependência de largura de banda e buffers internos: estruturas como reorder buffers e filas de load/store são limitadas por núcleo.</li>
</ul>
<p>Esses recursos compartilhados significam que duas hardware threads no mesmo núcleo não oferecem isolamento equivalente ao de dois núcleos físicos. Tratar cada hardware thread como uma CPU independente ignora dependências microarquiteturais e pode degradar throughput e previsibilidade ao induzir contenção e conflitos que o sistema não prevê.</p>
<p>Em outras palavras: o escalonador que vê apenas &ldquo;CPUs lógicas&rdquo; perde contexto sobre contendas internas do núcleo — um fator crítico quando buscamos baixa latência e previsibilidade.</p>
<h2 id="onde-os-schedulers-modernos-erram">Onde os schedulers modernos erram</h2>
<p>Muitos escalonadores expõem cada hardware thread lógico como uma CPU separada (p. ex. quando <code>htop</code> mostra &ldquo;cores lógicos&rdquo;). Essa abstração facilita balanceamento de carga, mas apaga a topologia real: quando cargas pesadas são espalhadas por hardware threads de um mesmo núcleo, surgem colisões internas que reduzem performance por watt e aumentam a variabilidade de latência.</p>
<p>O problema não é apenas teórico: medições podem mostrar degradação de <em>throughput</em> e latência em cenários que misturam cargas intensivas de CPU e sensíveis à latência, especialmente quando o escalonador não considera a afinidade por núcleo físico e a partição de recursos.</p>
<p>Por isso é importante que camadas de software acima do escalonador compreendam a topologia do processador ou que o próprio escalonador exponha políticas que evitem colocar cargas conflitantes em hardware threads do mesmo núcleo.</p>
<h2 id="a-proposta-do-fkernel-consciência-de-topologia">A proposta do FKernel: consciência de topologia</h2>
<p>No FKernel, a responsabilidade de lidar com essa complexidade é deslocada para camadas que entendem o perfil da carga. A ideia central é uma pipeline decidida antes do despacho para hardware threads:</p>
<p>Green Threads → Multilevel Feedback Queue (MLFQ) → Pervasive Layer → Hardware Threads (SMT)</p>
<p>Detalhes práticos:</p>
<ul>
<li>O MLFQ organiza e amostra comportamento das green threads para estimar sua sensibilidade à latência e ao throughput.</li>
<li>A Pervasive Layer usa esse perfil para decidir mapeamentos: algumas execuções ocupam uma hardware thread sozinho (para evitar contenda), outras são pareadas com cargas complementares para aproveitar vazios da unidade funcional.</li>
</ul>
<p>Isso torna o SMT um recurso gerenciado — um &ldquo;acelerador&rdquo; que é usado conscientemente e não um substituto direto de um núcleo físico.</p>
<p>Na prática, isso permite duas estratégias opostas: isolar workloads sensíveis à latência em hardware threads próprias, ou cooperar uma workload de alta utilização com outra complementar para maximizar uso de unidades funcionais sem bloquear latência crítica.</p>
<h3 id="flag-o_hpc--atalho-para-throughput">Flag <code>O_HPC</code> — atalho para throughput</h3>
<p>Para workloads puramente orientados a throughput, o desenvolvedor pode usar a flag <code>O_HPC</code>. Nesse modo, o caminho é encurtado: a aplicação solicita pinagem e afinidade mais agressivas (possivelmente com garantia de partição de cache L2/L3), sacrificando previsibilidade para ganhar rendimento bruto.</p>
<p>Em resumo, <code>O_HPC</code> é uma exceção explícita ao modelo orientado a latência — uma forma de o desenvolvedor indicar que prefere rendimento bruto em vez de previsibilidade quando as medições justificam essa escolha.</p>
<h2 id="conclusão">Conclusão</h2>
<p>Tratar hardware threads SMT como CPUs independentes é uma simplificação que não reflete a microarquitetura moderna: ela produz contenção interna, variabilidade de latência e desperdício de recursos. O FKernel propõe empurrar a complexidade para camadas que conhecem o perfil das cargas — MLFQ e Pervasive Layer — para mapear threads de forma consciente sobre a topologia real do processador.</p>
<p>O ganho esperado é simples e direto: menor latência, interatividade consistente e uso mais eficiente de caches e unidades funcionais. Para cargas de throughput extremo, a flag <code>O_HPC</code> permite abrir mão dessa previsibilidade de propósito.</p>
<p>Se você curte esse tipo de discussão ou quer acompanhar o desenvolvimento do FKernel, deixe um comentário, compartilhe como seu sistema lida com SMT ou sugira cargas de trabalho para testarmos. Medições práticas mostrarão o impacto real, e pretendo publicar os resultados em posts futuros.</p>
]]></content:encoded></item><item><title>OSDev: até onde dá para usar C++?</title><link>https://foxtechworld.github.io/osdev-ate-onde-da-para-usar-c/</link><guid isPermaLink="true">https://foxtechworld.github.io/osdev-ate-onde-da-para-usar-c/</guid><pubDate>Mon, 22 Sep 2025 15:33:40 -0300</pubDate><description>Veja quais recursos de C++ podem ser usados no desenvolvimento de um kernel e quais partes da runtime precisam ser implementadas pelo sistema operacional.</description><category>Programação</category><category>OSDev</category><category>OSDev</category><category>C++</category><category>Cpp</category><category>Kernel</category><category>Linux</category><category>Windows</category><category>MacOS</category><content:encoded><![CDATA[<p>Estou desenvolvendo um <a href="https://pt.wikipedia.org/wiki/N%C3%BAcleo_(sistema_operacional)">kernel</a> chamado <a href="https://github.com/KitsuneBSD/FKernel">FKernel</a>.</p>
<p>Para uso desktop em código x86_64.</p>
<p>E lendo sobre algumas linguagens como <strong><em>Rust</em></strong>, <strong><em>C</em></strong>, <strong><em>C++</em></strong>, <strong><em>Zig</em></strong> &hellip;</p>
<p>Decidi fazer uma combinação de:</p>
<ul>
<li>Linguagens de Programação:
<ul>
<li>C</li>
<li>C++</li>
</ul>
</li>
<li>Linguagem de montagem:
<ul>
<li>Nasm</li>
</ul>
</li>
</ul>
<p>Obviamente alguns podem estranhar já que eu propositalmente ignorei Rust, e aquelas que são considerados &ldquo;memory-safe&rdquo;.</p>
<h2 id="por-que-não-usar-linguagens-memory-safe">Por que não usar linguagens <em>memory-safe</em>?</h2>
<p>Pro Tip: Não existe linguagem memory-safe em baixo nível. Para programar um kernel ou similar, você vai depender do unsafe então nem tenta.</p>
<p>Se for para ter que lidar com sintaxes estranhas para programar um kernel, eu prefiro seguir no bom e velho C/C++.</p>
<p>Também não quero fazer um overflow de logs de um compilador super-nanny para chegar a um subset daquilo que eu queria no meu código.</p>
<h2 id="e-por-que-c">E por que C++?</h2>
<p>Muito tempo atrás Linus Torvalds havia tentado escrever um kernel com a versão de sua época.</p>
<blockquote>
<p>C++ leads to really, really bad design choices. You invariably start using the STL, boost, and other total and utter crap…</p>
</blockquote>
<p>Ok, podemos concordar em algumas partes mas, isso não seria inevitavelmente ruim.</p>
<p>Sim, C++ tem um monte de coisa, mas fugiria do ponto principal que é C++ dá contratos que structs sozinhas dificilmente conseguem.</p>
<p>Pegue um exemplo do <code>SerenityOS</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="k">static</span> <span class="n">ErrorOr</span><span class="o">&lt;</span><span class="n">NonnullOwnPtr</span><span class="o">&lt;</span><span class="n">KBuffer</span><span class="o">&gt;&gt;</span> <span class="n">try_create_with_size</span><span class="p">(</span><span class="n">StringView</span> <span class="n">name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="n">size_t</span> <span class="n">size</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="n">Memory</span><span class="o">::</span><span class="n">Region</span><span class="o">::</span><span class="n">Access</span> <span class="n">access</span> <span class="o">=</span> <span class="n">Memory</span><span class="o">::</span><span class="n">Region</span><span class="o">::</span><span class="n">Access</span><span class="o">::</span><span class="n">ReadWrite</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="n">AllocationStrategy</span> <span class="n">strategy</span> <span class="o">=</span> <span class="n">AllocationStrategy</span><span class="o">::</span><span class="n">Reserve</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">  <span class="k">auto</span> <span class="n">rounded_size</span> <span class="o">=</span> <span class="n">TRY</span><span class="p">(</span><span class="n">Memory</span><span class="o">::</span><span class="n">page_round_up</span><span class="p">(</span><span class="n">size</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">  <span class="k">auto</span> <span class="n">region</span> <span class="o">=</span> <span class="n">TRY</span><span class="p">(</span><span class="n">MM</span><span class="p">.</span><span class="n">allocate_kernel_region</span><span class="p">(</span><span class="n">rounded_size</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">access</span><span class="p">,</span> <span class="n">strategy</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nf">TRY</span><span class="p">(</span><span class="n">adopt_nonnull_own_or_enomem</span><span class="p">(</span><span class="k">new</span> <span class="p">(</span><span class="n">nothrow</span><span class="p">)</span> <span class="n">KBuffer</span> <span class="p">{</span> <span class="n">size</span><span class="p">,</span> <span class="n">move</span><span class="p">(</span><span class="n">region</span><span class="p">)</span> <span class="p">}));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Consegue entender o que esse código faz? Todo esse contrato engloba em poucas linhas</p>
<blockquote>
<p>Essa função try_create_with_size serve para criar um buffer de memória no kernel de um tamanho específico e lidar com possíveis erros de forma segura.</p>
</blockquote>
<p>Para termos o equivalente exato em C garantindo a mesma segurança seria necessária escrever dessa forma.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-C" data-lang="C"><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">try_create_with_size</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                         <span class="kt">size_t</span> <span class="n">size</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                         <span class="n">MemoryAccess</span> <span class="n">access</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                         <span class="n">AllocationStrategy</span> <span class="n">strategy</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                         <span class="n">KBuffer</span><span class="o">**</span> <span class="n">out_buffer</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">out_buffer</span><span class="p">)</span> <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">size_t</span> <span class="n">rounded_size</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">rc</span> <span class="o">=</span> <span class="nf">page_round_up</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">rounded_size</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="n">rc</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">MemoryRegion</span><span class="o">*</span> <span class="n">region</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rc</span> <span class="o">=</span> <span class="nf">allocate_kernel_region</span><span class="p">(</span><span class="n">rounded_size</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">access</span><span class="p">,</span> <span class="n">strategy</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">region</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="n">rc</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">KBuffer</span><span class="o">*</span> <span class="n">buffer</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">KBuffer</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">buffer</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">region</span><span class="o">-&gt;</span><span class="n">addr</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="nf">free</span><span class="p">(</span><span class="n">region</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="o">-</span><span class="n">ENOMEM</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">buffer</span><span class="o">-&gt;</span><span class="n">size</span> <span class="o">=</span> <span class="n">size</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">buffer</span><span class="o">-&gt;</span><span class="n">region</span> <span class="o">=</span> <span class="n">region</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="o">*</span><span class="n">out_buffer</span> <span class="o">=</span> <span class="n">buffer</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// sucesso
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Ok, tivemos uma disparidade no tamanho, mas isso não significa nada no geral.</p>
<p>Meu ponto defendido é que precisamos fazer muito mais código, que vai ser muito mais performático mas que vai resultar em um resultado muito menos seguro, e muito menos reusável no geral.</p>
<p>Não ironicamente, muitos empresas incluindo a própria Apple usam o C++ em seus kernels.</p>
<p>Mas não precisa ser o c++ inteiro e sim um subset chamado <a href="https://en.wikipedia.org/wiki/Embedded_C%2B%2B"><strong><em>embedded c++</em></strong></a>.</p>
<h3 id="implementação-do-iokit">Implementação do IOKit</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="cm">/*
</span></span></span><span class="line"><span class="cl"><span class="cm"> * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * This file contains Original Code and/or Modifications of Original Code
</span></span></span><span class="line"><span class="cl"><span class="cm"> * as defined in and that are subject to the Apple Public Source License
</span></span></span><span class="line"><span class="cl"><span class="cm"> * Version 2.0 (the &#39;License&#39;). You may not use this file except in
</span></span></span><span class="line"><span class="cl"><span class="cm"> * compliance with the License. The rights granted to you under the License
</span></span></span><span class="line"><span class="cl"><span class="cm"> * may not be used to create, or enable the creation or redistribution of,
</span></span></span><span class="line"><span class="cl"><span class="cm"> * unlawful or unlicensed copies of an Apple operating system, or to
</span></span></span><span class="line"><span class="cl"><span class="cm"> * circumvent, violate, or enable the circumvention or violation of, any
</span></span></span><span class="line"><span class="cl"><span class="cm"> * terms of an Apple operating system software license agreement.
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * Please obtain a copy of the License at
</span></span></span><span class="line"><span class="cl"><span class="cm"> * http://www.opensource.apple.com/apsl/ and read it before using this file.
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * The Original Code and all software distributed under the License are
</span></span></span><span class="line"><span class="cl"><span class="cm"> * distributed on an &#39;AS IS&#39; basis, WITHOUT WARRANTY OF ANY KIND, EITHER
</span></span></span><span class="line"><span class="cl"><span class="cm"> * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
</span></span></span><span class="line"><span class="cl"><span class="cm"> * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
</span></span></span><span class="line"><span class="cl"><span class="cm"> * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
</span></span></span><span class="line"><span class="cl"><span class="cm"> * Please see the License for the specific language governing rights and
</span></span></span><span class="line"><span class="cl"><span class="cm"> * limitations under the License.
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#ifndef _IOKIT_IONVRAMCONTROLLER_H
</span></span></span><span class="line"><span class="cl"><span class="cp">#define _IOKIT_IONVRAMCONTROLLER_H
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;IOKit/IOService.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">IONVRAMController</span> <span class="o">:</span> <span class="k">public</span> <span class="n">IOService</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">	<span class="n">OSDeclareAbstractStructors</span><span class="p">(</span><span class="n">IONVRAMController</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">public</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">	<span class="k">virtual</span> <span class="kt">void</span> <span class="n">registerService</span><span class="p">(</span><span class="n">IOOptionBits</span> <span class="n">options</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="n">APPLE_KEXT_OVERRIDE</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">virtual</span> <span class="kt">void</span> <span class="nf">sync</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">virtual</span> <span class="n">IOReturn</span> <span class="nf">select</span><span class="p">(</span><span class="kt">uint32_t</span> <span class="n">bank</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">	<span class="k">virtual</span> <span class="n">IOReturn</span> <span class="nf">eraseBank</span><span class="p">(</span><span class="kt">void</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">virtual</span> <span class="n">IOReturn</span> <span class="nf">read</span><span class="p">(</span><span class="n">IOByteCount</span> <span class="n">offset</span><span class="p">,</span> <span class="n">UInt8</span> <span class="o">*</span><span class="n">buffer</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	    <span class="n">IOByteCount</span> <span class="n">length</span><span class="p">)</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="k">virtual</span> <span class="n">IOReturn</span> <span class="nf">write</span><span class="p">(</span><span class="n">IOByteCount</span> <span class="n">offset</span><span class="p">,</span> <span class="n">UInt8</span> <span class="o">*</span><span class="n">buffer</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	    <span class="n">IOByteCount</span> <span class="n">length</span><span class="p">)</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#endif </span><span class="cm">/* !_IOKIT_IONVRAMCONTROLLER_H */</span><span class="cp">
</span></span></span></code></pre></div><p>Quem diria.</p>
<p>Se fossemos falar do C++ antes da versão 17, eu até concordaria mas após a versão 17 muita coisa mudou.</p>
<p>E veja que o IOKit é implementado na forma Embedded C++.</p>
<p>Mas, e como em tudo há um mas, há em real,o ponto da STL que invariavelmente você vai acabar usando ou não.</p>
<h3 id="realmente-preciso-do-stl">Realmente preciso do STL?</h3>
<p>No fringir dos ovos há um outro superset de C++ chamado <a href="https://terminalroot.com.br/2023/07/conheca-o-cpp-ortodoxo.html"><strong><em>c++ ortodoxo</em></strong></a> jamais o use, sério.</p>
<p>Uma das soluções que o FKernel e o SerenityOS fazem é criar sua própria STL.</p>
<p>O SerenityOS com sua <strong>Abstraction Kit</strong>.
E o FKernel com seu <strong>LibFK</strong>.</p>
<p>Usar uma STL não é de todo mal, há diversos efeitos, como otimização em cascata.</p>
<p>Genericos e todo resto.</p>
<h2 id="e-no-fim">E no fim?</h2>
<p>No fim, depende de você.</p>
<p>Se você está desenvolvendo um app para desktop.</p>
<p>Eu sugeriria:</p>
<ul>
<li><a href="https://pt.wikipedia.org/wiki/D_(linguagem_de_programa%C3%A7%C3%A3o)">D</a></li>
<li><a href="https://pt.wikipedia.org/wiki/Go_(linguagem_de_programa%C3%A7%C3%A3o)">Go</a></li>
<li><a href="https://pt.wikipedia.org/wiki/Zig_(linguagem_de_programa%C3%A7%C3%A3o)">Zig</a></li>
<li><a href="https://pt.wikipedia.org/wiki/Rust_(linguagem_de_programa%C3%A7%C3%A3o)">Rust</a></li>
</ul>
<p>Para baixo nível certamente eu sugeriria:</p>
<ul>
<li><a href="https://pt.wikipedia.org/wiki/B_(linguagem_de_programa%C3%A7%C3%A3o)">B</a></li>
<li><a href="https://pt.wikipedia.org/wiki/C_(linguagem_de_programa%C3%A7%C3%A3o)">C</a>,</li>
<li><a href="https://pt.wikipedia.org/wiki/C%2B%2B">C++</a></li>
<li><a href="https://pt.wikipedia.org/wiki/D_(linguagem_de_programa%C3%A7%C3%A3o)">D</a></li>
<li><a href="https://pt.wikipedia.org/wiki/Rust_(linguagem_de_programa%C3%A7%C3%A3o)">Rust</a></li>
<li><a href="https://pt.wikipedia.org/wiki/Zig_(linguagem_de_programa%C3%A7%C3%A3o)">Zig</a></li>
</ul>
<p>Mas em kernel estou muito mais satisfeito com minha escolha do que usar C puro.</p>
<p>Não que eu não use C obviamente, por baixo dos panos da LibFK eu implementei uma LibC bem simples com funções que eu teria que usar dentro do FKernel para algumas funções da LibFK.</p>
<p>Mas enfim, se uma linguagem que você prefere usar por algum motivo de design ou simplesmente por ser a que você sabe, simplesmente use.</p>
<p>Desde que não seja usar algo interpretado para fazer baixo nível, tá valendo tudo.</p>
]]></content:encoded></item></channel></rss>