<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Atomics on Jasper</title><link>https://jasper-aa64.github.io/tags/atomics/</link><description>Recent content in Atomics on Jasper</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 26 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jasper-aa64.github.io/tags/atomics/index.xml" rel="self" type="application/rss+xml"/><item><title>Trading System Notes #17: Wait-Free</title><link>https://jasper-aa64.github.io/posts/wait-free-sticky-counter/</link><pubDate>Mon, 26 Oct 2026 00:00:00 +0000</pubDate><guid>https://jasper-aa64.github.io/posts/wait-free-sticky-counter/</guid><description>Wait-free is not a faster lock-free: it turns a failed CAS from &amp;ldquo;try again&amp;rdquo; into &amp;ldquo;I come after you&amp;rdquo;, which bounds every thread&amp;rsquo;s steps, at the cost of more atomics and code that is harder to get right.</description></item><item><title>Trading System Notes #16: Spinlocks</title><link>https://jasper-aa64.github.io/posts/spinlock-implementation/</link><pubDate>Wed, 21 Oct 2026 00:00:00 +0000</pubDate><guid>https://jasper-aa64.github.io/posts/spinlock-implementation/</guid><description>Whether a spinlock is fast depends on what its waiters do: if every attempt is a read-modify-write, they drag the lock&amp;rsquo;s line back and forth. Read before you grab, put PAUSE in the loop, back off after losing, and waiting costs the holder almost nothing.</description></item><item><title>Low-Latency Trading — MESI Cache Coherence</title><link>https://jasper-aa64.github.io/posts/low-latency-mesi-cache-coherence/</link><pubDate>Sun, 04 Oct 2026 00:00:00 +0000</pubDate><guid>https://jasper-aa64.github.io/posts/low-latency-mesi-cache-coherence/</guid><description>MESI enforces one rule: a cache line has either one core that may write it or any number of cores that may only read it, never both. The four states are the answers to two questions — does anyone else hold this line, and have I changed it? — and every cost in the protocol comes from moving data between layers or waiting for another core to confirm. False sharing, a cached queue cursor and a producer that slows down as readers join are all the same state machine. Coherence still doesn&amp;rsquo;t make a multi-word read atomic, and it says nothing about the order of writes to different addresses; that is what fences are for.</description></item><item><title>Trading System Notes #5: An SPMC Broadcast Ring in Shared Memory</title><link>https://jasper-aa64.github.io/posts/spmc-shared-memory-broadcast-ring/</link><pubDate>Sun, 04 Oct 2026 00:00:00 +0000</pubDate><guid>https://jasper-aa64.github.io/posts/spmc-shared-memory-broadcast-ring/</guid><description>Market data has one producer and several consumers, each of which must see every message, and the producer is the hot path that may not wait for anyone. The answer is a broadcast ring: every slot carries its own sequence stamp, readers keep private cursors, and the producer overwrites the oldest slot without ever reading reader state. The price moves to the readers — overruns are silent, a re-check after reading can&amp;rsquo;t catch a half-written slot unless the writer invalidates the stamp first, and readers that catch up take the line the producer writes next, so every flat-out write costs more. Moving the ring into shared memory adds three more rules: nothing inside it may be a pointer, the first lap pays a page fault every 32 messages, and a restarted reader loses everything unless it saved its cursor.</description></item><item><title>Trading System Notes #4: Lock-Free Queues and Micro-Batching</title><link>https://jasper-aa64.github.io/posts/lock-free-queue-logger-micro-batching/</link><pubDate>Sun, 20 Sep 2026 00:00:00 +0000</pubDate><guid>https://jasper-aa64.github.io/posts/lock-free-queue-logger-micro-batching/</guid><description>A lock-free SPSC queue works because every shared variable has exactly one writer: each side updates only its own counter and merely reads the other&amp;rsquo;s. The rest is keeping that property from being quietly undone — a shared element count both cores fight over (subtract two counters instead), a full-check that reads the other core on every call (cache the other side&amp;rsquo;s cursor, which can only be wrong in the safe direction), a mirrored mapping that removes the wrap-around seam, and a logger that pushes one character per slot (thirty slots for one log line, five as text runs). It ends with the vocabulary that keeps lock-free claims honest: SPSC is wait-free only through a fail-fast interface, finite steps are not finite time, and a bounded queue must always choose between dropping and blocking.</description></item><item><title>Trading System Notes #2: Memory Ordering and Cache Lines</title><link>https://jasper-aa64.github.io/posts/memory-ordering-false-sharing-dependency-chains/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><guid>https://jasper-aa64.github.io/posts/memory-ordering-false-sharing-dependency-chains/</guid><description>The store buffer and the cache-coherence protocol are one piece of hardware, but they create two unrelated engineering problems. One is correctness: does a thread see the right value, in the right order — solved by memory_order and release/acquire pairing. The other is performance: how many cycles does touching shared or dependent data cost, even when every value read is already correct — solved by cache-line layout and instruction scheduling. Conflating the two is the single most common confusion in this part of systems programming.</description></item></channel></rss>