Intel TSX and Restricted Transactional Memory: When the CPU Speculates That Your Lock Was Unnecessary

2026-06-13

Restricted Transactional Memory (RTM) is Intel's hardware transactional memory extension. It exposes three instructions — XBEGIN, XEND, XABORT — that let you wrap a critical section in a hardware transaction. The CPU runs the code speculatively, buffers all writes in the L1 cache, and commits them atomically at XEND. If anything goes wrong (a conflicting access from another core, a cache eviction, a syscall, a page fault, an interrupt), the transaction aborts and execution jumps to a fallback handler.

The point is lock elision. If a lock is contended only rarely, taking it costs cache-line bouncing and serialization every time — even when no one else is touching the data. With RTM, you can speculatively skip acquiring the lock, do your work transactionally, and commit. If two threads collide, the transaction aborts and you fall back to actually taking the lock.

Concrete example: glibc's pthread_mutex_t with the PTHREAD_MUTEX_ELISION_NP type used to wrap lock/unlock in XBEGIN/XEND. A hash table guarded by such a mutex saw near-linear scaling under read-mostly workloads — because reads on different buckets didn't actually conflict, the transactions committed without ever touching the lock word. Under heavy write contention, abort rates spiked above 50% and elision was worse than a plain mutex.

Rule of thumb: a transaction's working set must fit in L1D — about 32 KB on most Intel cores, but in practice the cache's associativity (8-way) means any access pattern touching more than ~8 lines in the same set will abort. Plan for under 16 KB of touched data and under 1000 instructions per transaction. Anything that causes an L1 eviction of a transactionally-read or written line aborts you. So does any syscall, CPUID, or page fault.

The catch that killed TSX: in 2014 Intel disabled TSX on Haswell and early Broadwell via microcode update because of TAA (TSX Asynchronous Abort), a Meltdown-class side channel where aborted transactions leaked data through cache state. Most server SKUs from 2019 onward ship with TSX disabled by default. Check cpuid leaf 7, EBX bit 11 (RTM) — and then check whether the kernel disabled it via tsx=off.

The fallback path matters more than the fast path. XBEGIN takes a relative address — on abort, EAX contains a bitmask telling you why (conflict, capacity, explicit XABORT, retry-possible). Production code retries 2-3 times on transient aborts, then falls back to the real lock. Get this wrong and you livelock under load.

Key Takeaway: RTM lets the CPU speculatively skip locks and roll back on conflict, but its 16 KB working-set limit, syscall-induced aborts, and post-TAA microcode disablement make it a niche optimization rather than the lock-free panacea it was sold as.

All newsletters