MMgr v1.0.0
Zero-heap memory manager in C11. One borrowed buffer, carved by asserted offset.
Loading...
Searching...
No Matches
Roadmap

What is next, and what is deliberately not.

Next

Interop suites. test/interop/ is a directory with a README and no suites, because interop means checking the wire formats against another implementation and there is not one yet. The integration directory is no longer empty: test_read_bounds, test_hostile_content, test_scan_reference, test_tenant_lifecycle, test_text_pipeline and test_wire_roundtrip all live there.

Documented dispatch loculi, or a decision not to. ~180 undocumented symbols are the members of the <Mod>Ns tables. Either they get documented, or the reference makes it obvious that a loculus's prose lives on the free function it points at. See Documented symbol coverage.

A generator toolchain for the derived documentation. The module table, the configuration table, the glossary and the symbol index are all derivable from the tree, and are currently maintained by hand, which is exactly how "seventeen small modules" survived in a comment until there were nineteen.

Done since this was written

The unit suites are no longer thin. 240 targets at 100% of lines, branches and functions, and the whole suite runs a second time with MMGR_ORACLE_LIBC on so libc answers the same questions. What that turned up is in The test suite and Numbers, and how far they can be trusted, a parser that was returning the right double 16% of the time, a search that read up to seven bytes past its cap, an exponent that silently became zero past 1e308.

Per-unit optimization levels. mmgr_add_module takes OPTIMIZE, and the measurement behind each use of it is in What each optimization level costs.

Later

A second concurrency shape. The ring is single-producer single-consumer. Multi-producer is a different data structure, not a flag on this one, and it should stay out until something needs it.

More anchor profiles. The byte-frequency tables for substring search cover generic, English, URI, inet and route. Adding one is a header and a define; the question is only whether a workload justifies it.

Deliberately not

A page of non-goals is worth more than a page of goals, because it stops arguments.

A general allocator. No free lists and no size classes. If a workload needs those, it needs a heap, and MMgr is the wrong shape for it. Adding a general free would take away the property the whole library exists for: a footprint decided before the program runs.

Runtime configuration. Every knob is a compile-time define. A runtime-sized pool would move allocation failure from configure time back to run time, the very thing being avoided.

install() rules and a binary artifact. The ABI is a function of the compile-time widths. A prebuilt archive can silently disagree with its consumer about the size of embed_word. Consuming the source makes that impossible. See Adding MMgr to a build.

Compiler intrinsics in the scan path. Measured and rejected. See Doing eight bytes at a time. Beyond the performance answer, keeping them out keeps every compiler conditional in one file.

Locks. A cellblock is shared on atomic words, each boundary, claim and count moved in one step, and no context waits for another. A lock inside a bump allocator is a lock on the hot path of a library whose whole claim is bounded, predictable cost, and there is none.

Versioning

The version is 1.0.0 and the API is stable. It stands in five places: CMakeLists.txt, library.json, library.properties, CITATION.cff and sonar-project.properties, with nothing to keep them in step. A generator for them is open work.