0x7f3a1c000000

C · Linux 6.8 · 2026

sysipc

A Linux character driver that maps shared pages into two processes, with a lock-free ring buffer on top and poll/epoll support for blocking.

throughput
24M msg/s
round-trip p50, 43× lower than sockets
252 ns
idle CPU, down from 100%
0.3%
sysipc versus a Unix domain socket: 23.3 versus 1.62 million messages per second, and round-trip latency of 252 versus 10,894 nanoseconds at the median. Throughput, Mmsg/shigher is better0510152025sysipc ring: 23.3 Mmsg/ssysipc ring23.3Unix socket: 1.62 Mmsg/sUnix socket1.62Round-trip latencylog scale, lower is better100 ns1K ns10K ns100K nssysipc ring: p50 252 ns, p99 384 ns252 ns384 nsUnix socket: p50 10.9 µs, p99 55.7 µs10.9 µs55.7 µsmedian (p50)p99
sysipc ring versus Unix domain socket
TransportMmsg/sp50p99
sysipc ring23.3252 ns384 ns
Unix socket1.6210.9 µs55.7 µs
Against a Unix domain socket, the fastest socket Linux offers. 64-byte messages, medians of 20 runs.

Mechanism

A custom mmap handler allocates, splits and refcounts physical pages into userspace with alloc_pages, split_page and vm_insert_page. The ring is single-producer single-consumer on C11 acquire/release atomics, checked with 10M-message strict-ordering tests.

The hard part

Blocking without burning a core. A kernel wait queue plus a shared wait flag and adaptive spinning removed 99.2% of wakeup syscalls, and getting it right meant fixing a StoreLoad race that acquire/release ordering does not cover.

Throughput against spin limit: 6.4 million messages per second at 10, rising to 17 by 100 and flat after that, below the 24.1 of pure spinning. Mmsg/s0510152025101001K10Kspin limit, iterations (log scale)spin only, no blocking: 24.06spin limit 10: 6.37 Mmsg/sspin limit 50: 14.5 Mmsg/sspin limit 100: 17.06 Mmsg/sspin limit 500: 17.3 Mmsg/sspin limit 1000: 16.7 Mmsg/sspin limit 2000: 17.91 Mmsg/sspin limit 5000: 17.11 Mmsg/sspin limit 10000: 17.2 Mmsg/s6.37knee near 100
Throughput by spin limit
Spin limitMmsg/s
106.37
5014.5
10017.06
50017.3
100016.7
200017.91
500017.11
1000017.2
Spinning briefly before sleeping. Past ~100 iterations the budget stops mattering.
Throughput by consumer strategy: spinning reaches 24.1 million messages per second but burns a core while idle; kicking on every push drops to 3.5; conditional kicking with adaptive spin recovers 17.3 at 0.3% idle CPU. 0510152025Mmsg/sSpin only: 24.06 Mmsg/s, ~100% idle CPUSpin only~100% idle CPU24.06poll, kick on every push: 3.46 Mmsg/s, ~0.3% idle CPUpoll, kick on every push~0.3% idle CPU3.46poll, conditional kick + adaptive spin: 17.3 Mmsg/s, ~0.3% idle CPUpoll, conditional kick + adaptive spin~0.3% idle CPU17.3
Throughput and idle CPU by consumer strategy
ModeMmsg/sIdle CPU
Spin only24.06~100% idle CPU
poll, kick on every push3.46~0.3% idle CPU
poll, conditional kick + adaptive spin17.3~0.3% idle CPU
Three ways to block. The last keeps 72% of spinning throughput at 0.3% idle CPU.