|
libmizu 0.0.1
Lock-free shared-memory IPC
|
libmizu is a C library for lock-free shared-memory IPC.
libmizu is for runtimes that parallelize with processes rather than threads. It makes the communication between those processes fast enough to divide work at thread granularity.
libmizu uses shared memory as the fastest IPC transport. Processes read and write into shared memory directly, with no kernel involvement and no data copies through system sockets. This means round trips drop from tens of microseconds over sockets to under a microsecond (see Performance).
Channels and work-stealing task pools run over POSIX shared memory (Linux, macOS) or Win32 file mappings (Windows). The hot path stays in user space. Data moves through single-producer single-consumer rings with batched publication. Waiting is spin-then-park, and peer death arrives as an OS event.
Bindings share one wire format, so processes in different languages can exchange data over the same channel. The first-party bindings are mizu for R and pymizu for Python. Writing a binding covers other languages.
__ulock, or WaitOnAddress per platformmizu_status sentinels on hot pathsPre-release. The API is not stable and can change at any time before a release.
Representative figures from the C bench suite (make bench), measured on an Apple M4 Pro (macOS, arm64).
| Benchmark | Best observed |
|---|---|
| Channel round trip (nil / 64 B payload) | 0.3–0.4 µs |
| Channel round trip (64 KiB, arena tier) | 4.0 µs |
| Channel round trip (1 MiB, spill tier) | 50 µs |
| Channel batch throughput (64 B, batches of 32) | 44 M msgs/s |
| Pool submit + collect (nil payload) | 0.4 µs |
| Pool submit + collect (4 KiB payload) | 1.0 µs |
| Pool task throughput (tiny echo tasks) | ~11 M tasks/s |
The full dated records, including parker wake latency and spill-region costs, live in bench/notes.md.
This example makes a channel between two processes with the built-in bytes binding. The bytes binding needs no callbacks, so the example compiles as written. The host:
The peer fills its binding with mizu_binding_bytes() too and attaches with mizu_channel_attach(&ch, token, &binding). It reads the bootstrap payload with mizu_channel_drop() and signals mizu_channel_ready_set().
To move a language's own objects rather than byte buffers, register callbacks on the binding instead — the binding-author seam covered in Writing a binding:
include/mizu.h documents the full contract for each declaration: ownership, threading, and the mizu_status values that each verb returns. `DESIGN.md` gives the invariants. The rendered API reference lives at shikokuchuo.net/libmizu.
A binding teaches libmizu to turn the language's values into frames and back. The stage and read callbacks from the quickstart do the conversion, and exec runs tasks on pool workers. libmizu does the rest: the rings, waiting and waking, peer-death detection, and work-stealing. To start without callbacks, the built-in bytes binding — mizu_binding_bytes() — sends and receives byte buffers, as the quickstart shows.
Every operation is an exported function. A language with a foreign function interface can call libmizu from the shared library, with no C of its own. Every handle is opaque, so libmizu's internals can change without breaking the binding. Bindings that compile C can add the amalgamation to their own build instead: tools/amalgamate.sh writes mizu.c, mizu.h, and mizu_ext.h.
The headers form two tiers:
mizu.h** — the stable consumer API. The soname tracks its ABI. The stability promise starts at 1.0.mizu_ext.h** — the binding-author API: the callback seam (stage, read, exec, ...), the stager/read/publish services, the built-in bytes binding, and promoted internals (parker, liveness, preamble, map support). It is version-pinned per minor release and can change without deprecation. Binding authors rebuild (or re-vendor) per minor release.A third header, src/internal.h, is private. It is never installed, and bindings never include it.
libmizu needs a C11 compiler and a 64-bit platform: the wire formats depend on lock-free 64-bit atomics. On Linux, kernel 5.3 or later is required.
The Makefile is the only build system:
On Windows, run tools\build-win.bat instead. The script builds with clang-cl because MSVC C11 atomics are experimental, and it needs LLVM (clang-cl) and the Visual Studio C++ build tools. GitHub Windows runners have both preinstalled.
Static builds need no defines: MIZU_API is empty by default. This covers vendored and amalgamated builds: the first-party packages compile the sources into their own modules. If you build libmizu as a shared library, define MIZU_SHARED. If you compile the library itself on Windows, also define MIZU_BUILDING. The Makefile and build-win.bat set these defines for you.
To generate the amalgamation, run:
The repository layout and contributor notes live in CONTRIBUTING.md.
MIT. LICENSE.note has the third-party attributions (RngStreams jump matrices, vendored doxygen stylesheet).