<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>bitonic's blog.</title>
        <link>http://mazzo.li</link>
        <description><![CDATA[Often in error, never in doubt.]]></description>
        <atom:link href="http://mazzo.li/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Tue, 17 Feb 2026 00:00:00 UT</lastBuildDate>
        <item>
    <title>A vibe-coded alternative to YieldGimp</title>
    <link>http://mazzo.li/posts/vibe-coded-gilts.html</link>
    <description><![CDATA[<div id="title">
  <a id="logo" href="/archive.html">&#8592;</a>
</div>
<div id="wrapper" class="article">
<h1><em class="date"><span>2026-02-17</span></em> A vibe-coded alternative to YieldGimp</h1>


<p>If you’re a UK tax resident, short-term low-coupon gilts are the most tax efficient way to get savings-account-like returns, since most of their yield is tax free. This makes them very popular amongst retail investors, which now <a href="https://archive.is/cEUtf">hold a large portion</a> of the tradable low-coupon gilts.</p>
<p><a href="http://YieldGimp.com">YieldGimp.com</a> used to be a great free resource to evaluate the gilts currently available. However, it was recently turned into an app rather than a simple webpage. I’m not even sure if the app is free or paid, but I do not want to install the “YieldGimp platform” to quickly check gilt metrics when I buy them.</p>
<p>So I asked my LLM of choice to produce an alternative, and after a few minutes and a few rounds of prompting I had something that served my needs. It is available for use at <a href="https://mazzo.li/gilts/">mazzo.li/gilts/</a>, and the source is <a href="https://github.com/bitonic/gilts-app">on GitHub</a>.</p>
<p>It differs from YieldGimp in that it does not show metrics based on the current market price, but rather requires the user to input a price. I find this more useful anyway, since gilts are somewhat illiquid on my broker, so I need to come up with a limit price myself, which means that I want to know what the yield is at my price rather than the market price. It also lets you select a specific tax rate to produce a “gross equivalent” yield.</p>
<p>It is not a very sophisticated tool and it doesn’t pretend to model gilts and their tax implications precisely (the repository’s <a href="https://github.com/bitonic/gilts-app/blob/master/README.md#yield-model-used">README</a> has more details on its shortcomings), but for most use cases it should be informative enough to sanity-check your trades without a Bloomberg terminal.</p>


<div class="footer">
  <hr>
  <a href="mailto:f@mazzo.li">f@mazzo.li</a> &middot; <a href="https://twitter.com/trascendentale">twitter</a> &middot; <a href="https://mastodon.social/@francesco">mastodon</a> &middot; <a href="https://github.com/bitonic/mazzo.li/blob/master/posts/vibe-coded-gilts.md">source</a>
</div>

<div id="comments"></div>

</div>
]]></description>
    <pubDate>Tue, 17 Feb 2026 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/vibe-coded-gilts.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>Hidden benefits of undefined behavior</title>
    <link>http://mazzo.li/posts/undefined-behavior.html</link>
    <description><![CDATA[<div id="title">
  <a id="logo" href="/archive.html">&#8592;</a>
</div>
<div id="wrapper" class="article">
<h1><em class="date"><span>2025-10-17</span></em> Hidden benefits of undefined behavior</h1>


<p>I was reviewing some code at work, and something jumped at me when reading some arithmetic:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="kw">inline</span> <span class="dt">int64_t</span> int32ToDecimal9<span class="op">(</span><span class="dt">int32_t</span> i<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> i <span class="op">*</span> <span class="dv">1000000000</span><span class="op">;</span> <span class="op">}</span></span></code></pre></div>
<p>If you’ve had the good fortune of dealing with C or C++ for extended periods you would have recognized the problem. <code>i * 1000000000</code> will be performed with 32-bit precision, which is almost certainly not what the programmer intended since it will lead to an overflow for any <code>i</code> outside <span class="math inline">[-2, +2]</span>.</p>
<p>So far so good, a classic C footgun – we’ve all been there.</p>
<p>However code using this function was running, and working, which was more surprising. Take a moment to consider why before revealing the solution.</p>
<details>
<summary>
Reveal
</summary>
<p>A direct compilation of <code>int32ToDecimal9</code> will look something like this:</p>
<pre><code>imul    eax, edi, 1000000000
cdqe</code></pre>
<p>First, perform 32-bit signed multiplication, then sign-extend the result into 64-bit.</p>
<p>However, signed overflow is undefined behavior, so an optimizing compiler might prefer to do the sign extension <em>before</em> as part of a <code>mov</code> that it needed to do anyway, and then do the multiplication in 64 bits, thereby saving one instruction and “fixing” our bug in the process.</p>
<p>So we have a rare case of two C footguns cancelling each other out, rather than combining into an even bigger footgun as usual.</p>
</details>


<div class="footer">
  <hr>
  <a href="mailto:f@mazzo.li">f@mazzo.li</a> &middot; <a href="https://twitter.com/trascendentale">twitter</a> &middot; <a href="https://mastodon.social/@francesco">mastodon</a> &middot; <a href="https://github.com/bitonic/mazzo.li/blob/master/posts/undefined-behavior.md">source</a>
</div>

<div id="comments"></div>

</div>
]]></description>
    <pubDate>Fri, 17 Oct 2025 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/undefined-behavior.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>Open sourcing TernFS, a distributed filesystem</title>
    <link>http://mazzo.li/posts/ternfs.html</link>
    <description><![CDATA[<div id="title">
  <a id="logo" href="/archive.html">&#8592;</a>
</div>
<div id="wrapper" class="article">
<h1><em class="date"><span>2025-09-25</span></em> Open sourcing TernFS, a distributed filesystem</h1>


<p>A few days ago we open sourced TernFS, a distributed filesystem which has been used in production at <a href="https://www.xtxmarkets.com/">XTX</a> for a couple of years now. The project took up a big chunk of my waking hours for a year and a half, and I’m extremely happy that we are now sharing it with the world.</p>
<p>You can find a blog post describing it on <a href="https://www.xtxmarkets.com/tech/2025-ternfs/">XTX’s tech blog</a>, and the source code <a href="https://github.com/XTXMarkets/ternfs">on GitHub</a>. The repository contains the full git history, which is somewhat unusual for these sort of projects: you can see how the codebase grew rapidly from prototype into a production system.</p>


<div class="footer">
  <hr>
  <a href="mailto:f@mazzo.li">f@mazzo.li</a> &middot; <a href="https://twitter.com/trascendentale">twitter</a> &middot; <a href="https://mastodon.social/@francesco">mastodon</a> &middot; <a href="https://github.com/bitonic/mazzo.li/blob/master/posts/ternfs.md">source</a>
</div>

<div id="comments"></div>

</div>
]]></description>
    <pubDate>Thu, 25 Sep 2025 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/ternfs.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>How to store Go pointers from assembly</title>
    <link>http://mazzo.li/posts/go-asm-pointers.html</link>
    <description><![CDATA[The standard Go toolchain comes with an assembler out of the box. Said assembler is highly idiosyncratic, using syntax inherited from Plan 9 and choosing its own names for platform-specific instructions and registers. But it's great to have it readily available. More mundanely, Go comes with a garbage collector. This post explains how to make these two components play nice, if we want to manipulate Go pointers from our assembly.]]></description>
    <pubDate>Mon, 23 Jun 2025 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/go-asm-pointers.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>`inline-verilog`: Execute Verilog circuits from Haskell</title>
    <link>http://mazzo.li/posts/inline-verilog.html</link>
    <description><![CDATA[<div id="title">
  <a id="logo" href="/archive.html">&#8592;</a>
</div>
<div id="wrapper" class="article">
<h1><em class="date"><span>2025-06-09</span></em> <code>inline-verilog</code>: Execute Verilog circuits from
Haskell</h1>


<p>Like for most of the past 13 years, early June meant attending <a href="https://zfoh.ch/zurihac2025/">ZuriHac</a>. The event was as pleasant and well organized as ever.</p>
<p>While talking to Ed Kmett he half-jokingly mentioned that it would be useful to have a Verilog analogue of <a href="/posts/inline-c.html"><code>inline-c</code></a>, especially to test Verilog circuits against Haskell functions.</p>
<p>A few hours later I had <a href="https://github.com/fpco/inline-c/tree/master/inline-verilog"><code>inline-verilog</code></a>, which lets to do just that.</p>
<p><code>inline-verilog</code> allows you to embed “nameless” Verilog modules right in your Haskell:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TemplateHaskell #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE QuasiQuotes #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE ScopedTypeVariables #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Language.Verilog.Inline</span> <span class="kw">as</span> <span class="dt">V</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Word</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Foreign.Marshal.Alloc</span> (alloca)</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Foreign.Storable</span> (peek)</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>V.verilog</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="ot">adder ::</span> <span class="dt">Word16</span> <span class="ot">-&gt;</span> <span class="dt">Word16</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Bool</span>, <span class="dt">Word16</span>)</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>adder a b <span class="ot">=</span> alloca <span class="op">$</span> \<span class="fu">sum</span> <span class="ot">-&gt;</span> alloca <span class="op">$</span> \carry_out <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  [V.block<span class="op">|</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">module</span> (</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>        input  [<span class="dv">15</span><span class="op">:</span><span class="dv">0</span>] a,</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>        input  [<span class="dv">15</span><span class="op">:</span><span class="dv">0</span>] b,</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>        output [<span class="dv">15</span><span class="op">:</span><span class="dv">0</span>] <span class="fu">sum</span>,</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>        output        carry_out</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>    );</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>        assign {carry_out, <span class="fu">sum</span>} <span class="ot">=</span> a <span class="op">+</span> b;</span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    endmodule</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span>]</span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>  (,) <span class="op">&lt;$&gt;</span> peek carry_out <span class="op">&lt;*&gt;</span> peek <span class="fu">sum</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a><span class="ot">main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> <span class="fu">print</span> <span class="op">=&lt;&lt;</span> adder <span class="dv">1</span> <span class="dv">2</span></span></code></pre></div>
<p>The example above will print <code>(False,3)</code>.</p>
<p>Input and output arguments are expected to be present in the Haskell context in which the <code>V.block</code> is called. The Haskell types for the input and outputs are automatically inferred from the Verilog code. The output arguments are expected to be pointers in which the outputs will be stored.</p>
<p>Verilog code can also be factored out within a Haskell file using <code>V.verbatim</code>. See <a href="https://github.com/fpco/inline-c/blob/master/inline-verilog/test/tests.hs"><code>tests.hs</code></a> for a more complex example.</p>
<p>The way <code>inline-verilog</code> works is by invoking <code>verilator</code> to compile each Verilog block to C++, generating C stubs which execute the verilated circuit, and linking everything up with the Haskell executable.</p>
<p>There are some limitations, namely I haven’t implemented or tested:</p>
<ul>
<li>Inputs/outputs wider than 64 bits.</li>
<li><code>struct</code> ports.</li>
<li>Multidimensional input/output ports, e.g. <code>reg [15:0] foo [3:0][3:0]</code> .</li>
<li>Importing.</li>
</ul>
<p>All of the above should be easy, but it did not fit in the couple of hours it took to cook <code>inline-verilog</code> to its current state.</p>
<p>Also, <code>inline-verilog</code> does not make much sense for non-combinatorial circuits (i.e. stuff that does IO). But to test functional units, it should do the job.</p>


<div class="footer">
  <hr>
  <a href="mailto:f@mazzo.li">f@mazzo.li</a> &middot; <a href="https://twitter.com/trascendentale">twitter</a> &middot; <a href="https://mastodon.social/@francesco">mastodon</a> &middot; <a href="https://github.com/bitonic/mazzo.li/blob/master/posts/inline-verilog.md">source</a>
</div>

<div id="comments"></div>

</div>
]]></description>
    <pubDate>Mon, 09 Jun 2025 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/inline-verilog.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>Waiting for many things at once with `io_uring`</title>
    <link>http://mazzo.li/posts/uring-multiplex.html</link>
    <description><![CDATA[When doing systems programming we often need to wait for something to happen. Common examples might be waiting for some data to come through a socket or waiting on a lock. We also often want to wait on any of several conditions to become true. A web server might be handling many sockets at once, waiting for any number of them to become readable or writeable. This short blog post is concerned with the latter scenario in Linux. Until recently there was no generic framework which allowed us to wait on many arbitrary events, but now there is, thanks to `io_uring`.]]></description>
    <pubDate>Sun, 22 Sep 2024 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/uring-multiplex.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>CRC-32C tips and tricks</title>
    <link>http://mazzo.li/posts/crc-tips.html</link>
    <description><![CDATA[In a companion blog post I talked about how to effectively combine Reed-Solomon coding and CRCs. To do so I presented a few functions to manipulate CRCs. In this post I'll explain why and how they can be implemented.]]></description>
    <pubDate>Mon, 01 Jul 2024 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/crc-tips.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>CRCs and Reed-Solomon coding: better together</title>
    <link>http://mazzo.li/posts/rs-crc.html</link>
    <description><![CDATA[In my latest filesystem-themed post I discussed a technique to perform distributed resource management more safely. This time I'll explain how one might effectively combine _Reed-Solomon coding_ and _cyclic redundancy checks_. The first gives us redundancy (we can lose disks and still recover our data), the second protects us against data corruption.]]></description>
    <pubDate>Sun, 30 Jun 2024 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/rs-crc.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>Message authentication codes for safer distributed transactions</title>
    <link>http://mazzo.li/posts/mac-distributed-tx.html</link>
    <description><![CDATA[I've been developing and quickly deploying a distributed system, which is a class of software where bugs are expensive. A few hundred petabytes later, we haven't lost a single byte of data, also thanks to a simple trick which catches a large class of bugs when delegating responsibilities to possibly buggy software. It's a neat use of cryptography beyond security, so here's a small description.]]></description>
    <pubDate>Mon, 03 Jun 2024 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/mac-distributed-tx.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>
<item>
    <title>How to stop Linux threads cleanly</title>
    <link>http://mazzo.li/posts/stopping-linux-threads.html</link>
    <description><![CDATA[Stopping a Linux thread is a surprisingly annoying affair. In this post I present common pitfalls and some solutions -- although no truly satisfactory method exists.]]></description>
    <pubDate>Sun, 07 Jan 2024 00:00:00 UT</pubDate>
    <guid>http://mazzo.li/posts/stopping-linux-threads.html</guid>
    <dc:creator>Francesco Mazzoli</dc:creator>
</item>

    </channel>
</rss>
