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

The embedded_types headers every module builds on. More...

#include "embed_compiler_directives.h"
#include "embed_dispatch_layout.h"
#include "embed_types.h"
#include "memoriam_praetereo/memoriam_praetereo.h"
#include "memoria_externa/memoria_externa.h"

Go to the source code of this file.

Macros

#define MMGR_ALIGN_BYTES
 The DMA module, reached only when MMGR_ENABLE_DMA is set.
#define MMGR_ERROR_ATTR(msg_)
 Attribute that places a pool in external memory.
#define MMGR_ALLOC_SIZE(arg_)
 States which argument of an allocation entry gives the extent of what it returns.
#define MMGR_PARS_TOKEN(name_)
 Fails the link when a pool name is declared in a second translation unit.
#define MMGR_PARS_DECLARED_ONCE(name_)
 Fails the build when a pool name is declared a second time.
#define MMGR_PARS_CLAIMED_ONCE(name_)
 Fails the build when a pool is dressed a second time.
#define ParsMemoriaeInternae(name_, bytes_)
 Declares a pool of bytes in internal memory.
#define ParsMemoriaeHospes(name_)
 Declares a pool whose bytes the system gives at run time: its name, with no storage and no size.
#define ParsMemoriaeExternum(name_, bytes_)
 Declares a pool of bytes in external memory.
#define MMGR_ASSERT(cond_, msg_)
 Runtime assertion hook, inert here.
#define MMGR_FATAL(msg_)
 Stops the program on an illegal call, in every build.

Detailed Description

The embedded_types headers every module builds on.

Author
dstroy0 (Douglas Quigg) dquig.nosp@m.g123.nosp@m.@gmai.nosp@m.l.co.nosp@m.m
Date
2026-08-30
Note
Every module header includes this one. The widths, the word, the static assertion, the attribute wrappers, the dispatch layout assertions and the entry point macros all come from embedded_types, and nothing here declares an MMgr copy of any of them.
Only the two gated module headers below are included from here. A module includes what it needs itself, and an umbrella could not also be the header each module includes.
mmgr_string_shim.h is separate. Including it changes what the <string.h> names mean, which is a decision a consumer makes for itself.

Definition in file mmgr.h.

Macro Definition Documentation

◆ MMGR_ALIGN_BYTES

#define MMGR_ALIGN_BYTES

The DMA module, reached only when MMGR_ENABLE_DMA is set.

Note
memoriam_praetereo.h guards its own contents on MMGR_ENABLE_DMA as well.

The external memory module, reached only when MMGR_ENABLE_EXTRAM is set.

Note
memoria_externa.h guards its own contents on MMGR_ENABLE_EXTRAM as well.

Alignment a caller declares its own storage at before handing those bytes to a module.

Note
Nothing under src reads it. The tests, the benches and the region-edges example are what write EMBED_ALIGN(MMGR_ALIGN_BYTES) on their arrays. The default is 16.
Has to be a power of two, which the build checks below. It reaches an alignment specifier, and one given anything else is ill-formed. The check is here to name the knob, where the diagnostic would otherwise point at whichever array was declared with it.
Warning
Not the alignment a locus_carcerum cell comes back at. That is MMGR_CARCER_ALIGN, which is sizeof(embed_word), and nothing asserts the two agree.

Definition at line 59 of file mmgr.h.

◆ MMGR_ERROR_ATTR

#define MMGR_ERROR_ATTR ( msg_)

Attribute that places a pool in external memory.

Note
Named here and filled by the port. Which section a part puts external memory in is the part's business, and so this library names the knob and supplies no value for it. A build defines it ahead of this header, or on the command line.
Read only by ParsMemoriaeExternum, which is declared only where MMGR_ENABLE_EXTRAM is set.
Warning
Empty by default, and an external pool then lands wherever the linker puts an ordinary one. Nothing diagnoses that. A build enabling external memory has to supply this.

Marks a declaration so that a reference to it fails the build, carrying a message.

Parameters
[in]msg_Text the diagnostic reports, as a string literal.
Note
Reported at the site that referenced the declaration, and so the message names what a caller did. The linker can only say what it found. This is the reason to reach for it over a token: the linker names a symbol, this names the mistake.
Warning
The diagnostic arrives only where a reference survives to the end of compilation, and so what this marks has to be something nothing legitimately calls.
Expands to nothing where EMBED_HAS_ATTRIBUTE(error) is 0. A reference then compiles and the misuse goes unreported.

Definition at line 94 of file mmgr.h.

◆ MMGR_ALLOC_SIZE

#define MMGR_ALLOC_SIZE ( arg_)

States which argument of an allocation entry gives the extent of what it returns.

Parameters
[in]arg_One-based position of the byte count in the entry's parameter list.
Note
Feeds the compiler's object-size analysis, as lets a write past the cell a caller was given be reported at the line that wrote it. Without it the returned pointer carries the extent of the pool it came out of, and a cell overrun reads as a legal access.
Costs nothing. Measured byte-identical with and without, both for a direct call and for one through a dispatch table.
Warning
The bound survives only where the call is not folded away. An entry reached through its dispatch table keeps it; the same entry inlined at a direct call collapses to an offset into the pool and the cell-level extent is gone.
Expands to nothing where EMBED_HAS_ATTRIBUTE(alloc_size) is 0, ignoring arg_. The diagnostics it would have raised are not raised, and nothing reports that.

Definition at line 115 of file mmgr.h.

Referenced by mmgr_buf_grow(), mmgr_persistent_buf_alloc(), and mmgr_temporary_buf_alloc().

◆ MMGR_PARS_TOKEN

#define MMGR_PARS_TOKEN ( name_)

Fails the link when a pool name is declared in a second translation unit.

Parameters
[in]name_Pool being declared.
Note
An initialized object with external linkage, and so two units declaring one pool name give the linker two strong definitions of this symbol and it refuses them by name. The enumerator guard cannot see across a unit boundary; this is what does.
The pool's own array stays static, and so it is this token and not the bytes that collide. That keeps the storage private to its unit while the name stays answerable across all of them.
Warning
Costs one object per pool, in .bss or .data depending on the toolchain. Fixed and small, but not nothing on a part where pools are the point.

Definition at line 130 of file mmgr.h.

◆ MMGR_PARS_DECLARED_ONCE

#define MMGR_PARS_DECLARED_ONCE ( name_)

Fails the build when a pool name is declared a second time.

Parameters
[in]name_Pool being declared.
Note
The enumerator is the guard. A second declaration of one name collides on it, and the compiler prints the identifier, and so the identifier reads as the reason and names no mechanism.
Two pools of one name would sit at unique addresses and the language would take them. The name is all a consumer is handed. A name meaning internal memory in one place and external in another leaves the placement out of reach of the line that uses it, and those two differ in what a DMA engine can address and in settling time.
Warning
One translation unit is as far as this guard reaches. The enumerator is settled while a unit is compiled. A pool of the same name declared in a separate unit does not collide on it. Catching that one is the linker's to do, over a symbol it can see.

Definition at line 147 of file mmgr.h.

◆ MMGR_PARS_CLAIMED_ONCE

#define MMGR_PARS_CLAIMED_ONCE ( name_)

Fails the build when a pool is dressed a second time.

Parameters
[in]name_Pool being claimed.
Note
Emitted by whatever lays state over a pool - a cellblock, a ring, anything that writes its own records into those bytes. It sits here and in none of them, because the rule is the pool's and not a dresser's, and a copy in each would let the next dresser be written without one.
Keyed on the pool alone, with no dresser's name in it. Every other symbol a site emits carries the site's name, and so two sites over one pool collide only there and each would lay its own records over the same bytes while holding that it owned them.
Costs nothing. An enumerator emits no storage and is settled while the unit compiles.
Warning
Says a pool is dressed once. It says nothing about the bytes being reached directly, which is a separate question with separate guards.

Definition at line 168 of file mmgr.h.

◆ ParsMemoriaeInternae

#define ParsMemoriaeInternae ( name_,
bytes_ )

Declares a pool of bytes in internal memory.

Parameters
[in]name_Name the pool is reached by, which is also the array.
[in]bytes_Bytes in it.
Note
A pool is a block of bytes, alone. Hand it to LocusCarcerum to have it dressed as a cellblock, to mmgr_anular_init to have it dressed as a ring, or to a memor entry to work on it as the bytes it is. A pool nobody hands anywhere is a pool that exists and is unclaimed.
The count is carried as name_##_bytes as well as laid down as the array. A consumer has the extent without deriving it. The assertion is what compares the two, and it has content only because the two are produced separately.
Aligned to MMGR_ALIGN_BYTES, and that leaves that knob the contract it is documented as. No caller writes it out.

Definition at line 188 of file mmgr.h.

◆ ParsMemoriaeHospes

#define ParsMemoriaeHospes ( name_)

Declares a pool whose bytes the system gives at run time: its name, with no storage and no size.

Parameters
[in]name_Name the pool is reached by.
Note
The program asks the system for the bytes once, at the size it finds it needs, and hands them to the dresser. MemoriaAnularis over this pool gives a ring whose address the linker settles, whose state names the bytes wherever the system put them.
For bytes that must come from the system: a graphics device placing a buffer over them opens the allocation they are, which an array in the program's image is not.

Definition at line 209 of file mmgr.h.

◆ ParsMemoriaeExternum

#define ParsMemoriaeExternum ( name_,
bytes_ )

Declares a pool of bytes in external memory.

Parameters
[in]name_Name the pool is reached by, which is also the array.
[in]bytes_Bytes in it.
Note
The same declaration as ParsMemoriaeInternae, carrying MMGR_EXTRAM_ATTR. Which memory a pool sits in is settled by which of the two a caller writes, and nothing afterwards inspects an address to find out.
Warning
Declared only where MMGR_ENABLE_EXTRAM is set. A build without external memory fails on the name, where it would otherwise quietly place the bytes internally.

Definition at line 225 of file mmgr.h.

◆ MMGR_ASSERT

#define MMGR_ASSERT ( cond_,
msg_ )

Runtime assertion hook, inert here.

Parameters
[in]cond_Condition the caller expects to hold.
[in]msg_String literal describing the expectation.
Note
An expectation the library asserts is one a correct caller cannot break, and so the form here pays nothing for it. It expands to a sizeof, which type checks cond_ and never evaluates it.
A build wanting a failed expectation to report and stop defines its own ahead of this header, and the guard below stands down. test/support/mmgr_host_traps.h does this for the checks environment, and it is where the stdio and stdlib that reporting needs live.
Warning
Not a runtime check and cannot be read as one. A failed expectation produces no diagnostic and no trap in this form.
cond_ must carry no side effect, since this form never evaluates it.

Definition at line 252 of file mmgr.h.

◆ MMGR_FATAL

#define MMGR_FATAL ( msg_)

Stops the program on an illegal call, in every build.

Parameters
[in]msg_String literal naming what was violated.
Note
Separate from MMGR_ASSERT because the two answer different questions. MMGR_ASSERT states an expectation a correct caller cannot break, and it is inert in the build that ships. This one marks a call that is illegal to make, and so it has to hold in that build too.
Reached where continuing would be worse than stopping. A release handed a prisoner from another cellblock is the case it exists for: the caller has shown it does not know which cellblock owns that memory, and so its next release and its next allocation are both suspect, and on a maximum security cellblock a quiet return would leave bytes unzeroed that the caller believes were wiped.
Does not return. Every call site is written on that basis and carries no fallback after it.
The stop is unconditional and the diagnostic is not. The form here halts and names nothing, as keeps this header free of libc.
Warning
A build may define its own before including this header, and the form below is then not used. A target reporting a fault through its own handler wants that, and so does a test harness, which would otherwise hang on this form and never report a failure.
This form spins. A target without abort has no other way to stop, and a halt is what a debugger can catch.

Definition at line 279 of file mmgr.h.