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

Every module, stem and verb in the library, and what it means in plain English.

Why Latin at all

libc and <string.h> are everywhere, and these are not libc functions. They reach the same conclusion for the same input, across every domain: that is all they share. How they reach it is entirely different: the backend is machine-width parallel word processing throughout, bitmath is extensive, and SIMD within a register is used wherever it applies.

A name that collided with libc's would advertise a drop-in replacement of the implementation as well as of the result. The names also keep the library clear of a consumer's own vocabulary and of the half-dozen other things in an embedded codebase already called buffer, pool, arena or span.

That reason stands alone. It is not decoration, and it is not obscurity for its own sake: a module called spatium can be grepped for with confidence, and a symbol called mmgr_spat_from cannot be confused with anybody else's span. The cost is this page, which is a fair trade for never having to rename anything again.

tools/dev_env/names.tsv is the source of truth for the tables below.

Modules

The stem is the name of the module's dispatch table, and a call site reads it.

Latin stem in English
memoria_anularis anularis ring memory, the lock-free SPSC ring
memoria_externa exter external memory, the PSRAM pool
locus_carcerum place of prisons, the region and both its ends
spatium spat space, extent, a span
proximus_operor proxim nearest work, raw load and store
verbum_scrutor lane, mask, word word examiner, the SWAR scanner
memoria_operor memor memory work, the mem* family
cellularum_laboro cellul cell work, bounded string operations
verba_scribo verba I write words, the string writer
numeros_scribo numer I write numbers, the field formatter
transformo muto I transform, decimal to binary scaling
fractio fract a breaking, IEEE-754 field access
bitorum_introitus_exitus bitio entry and exit of bits, the bit writer
octetus_introitus_exitus byteio entry and exit of octets, byte transfers
endian parva_extremitas, magna_extremitas (English) byte order. small end, large end
ascii_persona_bitorum ascii character masks of bits, the class bitmaps
impensa_ancorae_acus ancorae cost of an anchor point, the frequency tables
memoriam_praetereo praet I pass memory by, DMA transfer submission
clz clz (English) count leading zeros
pow5 (English) powers of five for decimal work

Verbs

The verbs are where the Latin does the most work, because the English words were the ones most likely to mislead.

The public entries are English. A handle is assembled from its parts, [lifetime]_[security]_[what it is]_[action], with each part spent only where it disambiguates.

part values what it settles
lifetime persistent, temporary the sentence. How long the prisoner holds the cell
security max_security present only where the zeroing form has to be told from the plain one
what it is buf bytes, as against a count
action alloc, release what the entry does to them

So persistent_buf_alloc is lifetime//buf/alloc, and persistent_max_security_buf_release fills all four.

entry means why not the English
buf_available bytes at hand free_bytes reads as a verb, as though it frees something. It reports a count
buf_grow a cell made larger where it stands realloc moves a cell and reuses holes. This moves no other cell, and answers no where the cell is not its tier's newest

temporary_buf_alloc takes a cell from the temporary tier. persistent_buf_release takes the cell itself, of either tier, and gives it back, in any order, because the cell's own header carries its extent and its offset says which tier it lies in, and the release does not have to be told which one it is or when it was taken.

Types

type is
SeriesCellularum a cellblock's state: the pool it covers, its extent, and both tier ends
CarcerCell one cell's header: the payload behind it, and whether it is busy
mmgr_span a buffer, its capacity and a cursor. pos is how much was written
mmgr_cspan the read counterpart. len is the extent, err latches a short read
mmgr_ring opaque storage a caller declares for one ring
embed_word the machine word, unsigned. The SWAR carrier
embed_iword the machine word, signed. The same register as embed_word
embed_bool EMBED_TRUE or EMBED_FALSE

The embed_ types come from embedded_types, a separate library MMgr consumes. See Compilers, attributes and fallbacks.

Other terms this documentation uses

The prison is a teaching metaphor, and the vocabulary follows it end to end. Where memory management already has the exact word, persistent, temporary, alignment, header, that word ships, and the metaphor stays behind the name.

term means
borrow storage the library was handed and does not own. Everything is a borrow
pool a block of bytes, declared by ParsMemoriaeInternae or ParsMemoriaeExternum
facility one prison site, declared by LocusCarcerum
cellblock a housing unit inside a facility, dressed over one pool
custodia the guards posted to a cellblock, soluta or secura
soluta general population. Open, and a release leaves the bytes as they are
secura solitary. Controlled, and a release zeroes the cell first
cell one allocation, its header and the payload behind it
prisoner what an allocation hands back. Never a tenant
claim dressing a pool. It happens once, at the declaration, and the build enforces it
carrier the integer a SWAR operation runs on. Always the machine word
lane one byte inside the carrier
environment one set of compile-time widths. See The environment matrix
latch a flag that stays set once set. A run is checked once at the end

The two axes are independent, and that independence is the part to keep. Which custodia is the environment. It is fixed at the cellblock's declaration and governs how a release behaves. Persistent or temporary is the sentence, how long the prisoner holds the cell, and it is chosen per allocation. A long sentence in general population is an ordinary thing, and so is a short stay in solitary.

The naming law

Every public function is mmgr_<infix>_<tail>, where <infix> is the module's stem. spat.from is mmgr_spat_from, memor.cpy is mmgr_memor_cpy.

verbum_scrutor is the exception: its three tables are named for what they operate on, lane, mask, word, while the functions all carry the module's own infix, and lane.has_zero is mmgr_scrut_has_zero.

Three infixes do not name their module, and that is by design: they name distinct concepts inside proximus_operor, and collapsing them onto one stem would merge things that are not the same thing:

infix is
proxim an unaligned access
aequus an aligned access
migro an access that may alias

Merging the aligned and unaligned load is a miscompile the compiler cannot report. See Proximus operor: load and store.