29#ifndef MMGR_LOCUS_CARCERUM_H
30#define MMGR_LOCUS_CARCERUM_H
49#ifndef MMGR_ENABLE_HW_MEM_CAPACITY_CB
50#define MMGR_ENABLE_HW_MEM_CAPACITY_CB 0
52#if (MMGR_ENABLE_HW_MEM_CAPACITY_CB != 0) && (MMGR_ENABLE_HW_MEM_CAPACITY_CB != 1)
53#error "MMGR_ENABLE_HW_MEM_CAPACITY_CB must be 0 or 1"
62#ifndef MMGR_CARCER_OWNERS
63#define MMGR_CARCER_OWNERS 128u
72#ifndef MMGR_MOVABLE_SETTLE_PERCENT
73#define MMGR_MOVABLE_SETTLE_PERCENT 25u
75#if (MMGR_MOVABLE_SETTLE_PERCENT < 1u) || (MMGR_MOVABLE_SETTLE_PERCENT > 100u)
76#error "MMGR_MOVABLE_SETTLE_PERCENT must be from 1 to 100"
80#ifndef MMGR_MOVABLE_READ_MS
81#define MMGR_MOVABLE_READ_MS 100u
85#ifndef MMGR_MOVABLE_QUIET_READINGS
86#define MMGR_MOVABLE_QUIET_READINGS 3u
90#ifndef MMGR_MOVABLE_BACKOFF_MOST_MS
91#define MMGR_MOVABLE_BACKOFF_MOST_MS 25600u
94#include "embed_atomic.h"
95#include "embed_turnstile.h"
107#define MMGR_CARCER_ALIGN \
108 ((sizeof(embed_word) > _Alignof(embed_atomic_usize)) ? (size_t)sizeof(embed_word) \
109 : (size_t)_Alignof(embed_atomic_usize))
118 "the cellblock rounds offsets by masking, which needs a power of two alignment");
127 "MMGR_ALIGN_BYTES must be a multiple of MMGR_CARCER_ALIGN, the grain a cell's words stand on");
155 embed_atomic_usize
hw;
174#if MMGR_CARCER_OWNERS < 0x10u
175#define MMGR_OWNER_PLACE_BITS 4u
176#elif MMGR_CARCER_OWNERS < 0x20u
177#define MMGR_OWNER_PLACE_BITS 5u
178#elif MMGR_CARCER_OWNERS < 0x40u
179#define MMGR_OWNER_PLACE_BITS 6u
180#elif MMGR_CARCER_OWNERS < 0x80u
181#define MMGR_OWNER_PLACE_BITS 7u
182#elif MMGR_CARCER_OWNERS < 0x100u
183#define MMGR_OWNER_PLACE_BITS 8u
184#elif MMGR_CARCER_OWNERS < 0x200u
185#define MMGR_OWNER_PLACE_BITS 9u
186#elif MMGR_CARCER_OWNERS < 0x400u
187#define MMGR_OWNER_PLACE_BITS 10u
188#elif MMGR_CARCER_OWNERS < 0x800u
189#define MMGR_OWNER_PLACE_BITS 11u
190#elif MMGR_CARCER_OWNERS < 0x1000u
191#define MMGR_OWNER_PLACE_BITS 12u
192#elif MMGR_CARCER_OWNERS < 0x2000u
193#define MMGR_OWNER_PLACE_BITS 13u
194#elif MMGR_CARCER_OWNERS < 0x4000u
195#define MMGR_OWNER_PLACE_BITS 14u
196#elif MMGR_CARCER_OWNERS < 0x8000u
197#define MMGR_OWNER_PLACE_BITS 15u
198#elif MMGR_CARCER_OWNERS < 0x10000u
199#define MMGR_OWNER_PLACE_BITS 16u
201#error "MMGR_CARCER_OWNERS must be below 65536: the owner word's place field is 16 bits at the most"
203#define MMGR_OWNER_SIGNAL_BITS 3u
205 "the owner word must have a timestamp bit left after its place, completion and signaling bits");
206#define MMGR_OWNER_TIME_BITS (EMBED_WORD_BITS - MMGR_OWNER_PLACE_BITS - 1u - MMGR_OWNER_SIGNAL_BITS)
207#define MMGR_OWNER_TIME_MASK (((embed_atomic_usize_value)1u << MMGR_OWNER_TIME_BITS) - 1u)
208#define MMGR_OWNER_SIGNAL_SHIFT MMGR_OWNER_TIME_BITS
209#define MMGR_OWNER_COMPLETE ((embed_atomic_usize_value)1u << (MMGR_OWNER_TIME_BITS + MMGR_OWNER_SIGNAL_BITS))
210#define MMGR_OWNER_PLACE_SHIFT (MMGR_OWNER_TIME_BITS + MMGR_OWNER_SIGNAL_BITS + 1u)
211#define MMGR_OWNER_PLACE_MASK ((((embed_atomic_usize_value)1u << MMGR_OWNER_PLACE_BITS) - 1u) << MMGR_OWNER_PLACE_SHIFT)
213 "MMGR_CARCER_OWNERS must fit the owner word's place field");
231extern const size_t mmgr_owner_table_count;
239#define MMGR_OWNER_PLACE(name_, text_) mmgr_owner_place_##name_,
247#define MMGR_OWNER_RECORD(name_, text_) \
248 {(text_), (size_t)mmgr_owner_place_##name_ + 1u, EMBED_ATOMIC_INIT(0u), EMBED_ATOMIC_INIT(0u)},
256#define MMGR_OWNER_POINTER(name_, text_) const CellOwner *const name_ = &mmgr_owner_table[mmgr_owner_place_##name_];
264#define MMGR_OWNER_EXTERN(name_, text_) extern const CellOwner *const name_;
277#define MMGR_OWNERS(list_) \
280 list_(MMGR_OWNER_PLACE) mmgr_owner_table_laid \
282 EMBED_STATIC_ASSERT((size_t)mmgr_owner_table_laid <= (size_t)MMGR_CARCER_OWNERS, \
283 "more owners are declared than MMGR_CARCER_OWNERS allows"); \
284 CellOwner mmgr_owner_table[(size_t)mmgr_owner_table_laid] = {list_(MMGR_OWNER_RECORD)}; \
285 const size_t mmgr_owner_table_count = (size_t)mmgr_owner_table_laid; \
286 list_(MMGR_OWNER_POINTER)
305 return (
size_t)embed_atomic_usize_load(&owner->
in_use);
317 return (
size_t)embed_atomic_usize_load(&owner->
hw);
337#define MMGR_CARCER_HALF_BITS ((unsigned int)((sizeof(embed_atomic_usize_value) * 8u) / 2u))
338#define MMGR_CARCER_HALF_MASK ((embed_atomic_usize_value)(((embed_atomic_usize_value)1u << MMGR_CARCER_HALF_BITS) - 1u))
347#define MMGR_CARCER_BYTES_MOST ((size_t)1u << (MMGR_CARCER_HALF_BITS - 1u))
354#define MMGR_CARCER_WANT_MOST ((size_t)1u << (MMGR_CARCER_HALF_BITS - 8u))
394#if MMGR_ENABLE_HW_MEM_CAPACITY_CB
395 embed_atomic_usize persistent_hw;
396 embed_atomic_usize temporary_hw;
402#if MMGR_ENABLE_HW_MEM_CAPACITY_CB
403#define MMGR_CARCER_STATE_HW , EMBED_ATOMIC_INIT(0u), EMBED_ATOMIC_INIT(0u)
405#define MMGR_CARCER_STATE_HW
415#define MMGR_CARCER_STATE(base_, bytes_) \
418 EMBED_ATOMIC_INIT((embed_atomic_usize_value)(bytes_) << MMGR_CARCER_HALF_BITS), \
419 EMBED_ATOMIC_INIT(0u), \
420 EMBED_ATOMIC_INIT(0u), \
421 EMBED_ATOMIC_INIT(0u), \
422 EMBED_ATOMIC_INIT(0u), \
423 EMBED_ATOMIC_INIT(0u), \
424 EMBED_ATOMIC_INIT(0u), \
425 EMBED_ATOMIC_INIT(0u) MMGR_CARCER_STATE_HW, \
487#define MMGR_MOVABLE_HEAD_BYTES 192u
490#define MMGR_MOVABLE_CLAIM_BITS ((size_t)(8u * sizeof(embed_atomic_usize)))
501#define MMGR_MOVABLE_STORAGE_BYTES(cells_, width_, rows_) \
502 (MMGR_MOVABLE_HEAD_BYTES + \
503 (((cells_) + (((cells_) + MMGR_MOVABLE_CLAIM_BITS - 1u) / MMGR_MOVABLE_CLAIM_BITS) + (2u * (rows_))) * \
504 sizeof(embed_atomic_usize)))
517 return (
size_t)(embed_atomic_usize_load(&series->
bounds) & MMGR_CARCER_HALF_MASK);
555#if MMGR_ENABLE_HW_MEM_CAPACITY_CB
557 return (
size_t)embed_atomic_usize_load(&series->persistent_hw);
572#if MMGR_ENABLE_HW_MEM_CAPACITY_CB
574 return (
size_t)embed_atomic_usize_load(&series->temporary_hw);
595 void *(*persistent_buf_alloc)(
601 void *(*temporary_buf_alloc)(
607 void *prisoner,
size_t size,
619EMBED_TABLE_LAYOUT(
MinimumSecurityGuard, persistent_buf_alloc, persistent_buf_release, temporary_buf_alloc,
620 who_owns_buf, buf_available, buf_grow, movable_init, movable_buf_alloc, movable_buf_release,
621 movable_buf_read, movable_buf_write, movable_buf_compare, movable_buf_measure);
633 void *(*persistent_buf_alloc)(
638 void *(*temporary_buf_alloc)(
642 void *(*buf_grow)(
void *prisoner,
size_t size,
655EMBED_TABLE_LAYOUT(
MaximumSecurityGuard, persistent_buf_alloc, persistent_buf_release, temporary_buf_alloc,
656 who_owns_buf, buf_available, buf_grow, movable_init, movable_buf_alloc, movable_buf_release,
657 movable_buf_read, movable_buf_write, movable_buf_compare, movable_buf_measure);
667#define MMGR_CARCER_MOVABLE_ENTRIES(prisonsite_, name_, wipe_to_zero_on_release_, series_cellularum_) \
668 static embed_bool prisonsite_##_##name_##_movable_init(const CarcerMovableInitCfg *args) \
670 return mmgr_movable_init((series_cellularum_), args, (wipe_to_zero_on_release_)); \
672 static const CarcerMovableEntry *prisonsite_##_##name_##_movable_buf_alloc(size_t size, const CellOwner *owner) \
674 return mmgr_movable_buf_alloc((series_cellularum_), size, owner); \
676 static embed_bool prisonsite_##_##name_##_movable_buf_release(const CarcerMovableEntry *cell, \
677 const CellOwner *owner) \
679 return mmgr_movable_buf_release((series_cellularum_), cell, owner); \
681 static embed_bool prisonsite_##_##name_##_movable_buf_read(const CarcerMovableCfg *args) \
683 return mmgr_movable_buf_read((series_cellularum_), args); \
685 static embed_bool prisonsite_##_##name_##_movable_buf_write(const CarcerMovableCfg *args) \
687 return mmgr_movable_buf_write((series_cellularum_), args); \
689 static embed_iword prisonsite_##_##name_##_movable_buf_compare(const CarcerMovableCfg *args) \
691 return mmgr_movable_buf_compare((series_cellularum_), args); \
693 static size_t prisonsite_##_##name_##_movable_buf_measure(const CarcerMovableCfg *args) \
695 return mmgr_movable_buf_measure((series_cellularum_), args); \
720#define MMGR_CARCER_BODY(prisonsite_, type_, name_, wipe_to_zero_on_release_) \
721 MMGR_PARS_CLAIMED_ONCE(name_); \
722 EMBED_STATIC_ASSERT(sizeof(mmgr_pars_storage_##name_) >= (2u * MMGR_CARCER_ALIGN), \
723 #prisonsite_ "." #name_ " is too small for one cell"); \
724 EMBED_STATIC_ASSERT(sizeof(mmgr_pars_storage_##name_) <= MMGR_CARCER_BYTES_MOST, \
725 #prisonsite_ "." #name_ " is larger than a tier boundary's half word can name"); \
726 static SeriesCellularum prisonsite_##_##name_##_ctx = MMGR_CARCER_STATE(mmgr_pars_storage_##name_, name_##_bytes); \
727 MMGR_ALLOC_SIZE(1) static void *prisonsite_##_##name_##_persistent_buf_alloc(size_t size, const CellOwner *owner) \
729 if (wipe_to_zero_on_release_) \
731 return mmgr_persistent_max_security_buf_alloc(&prisonsite_##_##name_##_ctx, size, owner); \
733 return mmgr_persistent_buf_alloc(&prisonsite_##_##name_##_ctx, size, owner); \
735 static void prisonsite_##_##name_##_persistent_buf_release(void *prisoner, const CellOwner *owner) \
737 if (wipe_to_zero_on_release_) \
739 mmgr_persistent_max_security_buf_release(&prisonsite_##_##name_##_ctx, prisoner, owner); \
743 mmgr_persistent_buf_release(&prisonsite_##_##name_##_ctx, prisoner, owner); \
747 static void *prisonsite_##_##name_##_temporary_buf_alloc(size_t size, const CellOwner *owner) \
749 if (wipe_to_zero_on_release_) \
751 return mmgr_temporary_max_security_buf_alloc(&prisonsite_##_##name_##_ctx, size, owner); \
753 return mmgr_temporary_buf_alloc(&prisonsite_##_##name_##_ctx, size, owner); \
755 static embed_bool prisonsite_##_##name_##_who_owns_buf(const void *at) \
757 return mmgr_who_owns_buf(&prisonsite_##_##name_##_ctx, at); \
759 static size_t prisonsite_##_##name_##_buf_available(void) \
761 const size_t available = mmgr_buf_available(&prisonsite_##_##name_##_ctx); \
765 static void *prisonsite_##_##name_##_buf_grow(void *prisoner, size_t size, const CellOwner *owner) \
767 if (wipe_to_zero_on_release_) \
769 return mmgr_max_security_buf_grow(&prisonsite_##_##name_##_ctx, prisoner, size, owner); \
771 return mmgr_buf_grow(&prisonsite_##_##name_##_ctx, prisoner, size, owner); \
773 MMGR_CARCER_MOVABLE_ENTRIES(prisonsite_, name_, wipe_to_zero_on_release_, &prisonsite_##_##name_##_ctx)
785#define MMGR_CARCER_MEM(prisonsite_, type_, name_, wipe_to_zero_on_release_) type_ name_;
797#define MMGR_CARCER_SEAT(prisonsite_, type_, name_, wipe_to_zero_on_release_) \
798 {prisonsite_##_##name_##_persistent_buf_alloc, \
799 prisonsite_##_##name_##_persistent_buf_release, \
800 prisonsite_##_##name_##_temporary_buf_alloc, \
801 prisonsite_##_##name_##_who_owns_buf, \
802 prisonsite_##_##name_##_buf_available, \
803 prisonsite_##_##name_##_buf_grow, \
804 prisonsite_##_##name_##_movable_init, \
805 prisonsite_##_##name_##_movable_buf_alloc, \
806 prisonsite_##_##name_##_movable_buf_release, \
807 prisonsite_##_##name_##_movable_buf_read, \
808 prisonsite_##_##name_##_movable_buf_write, \
809 prisonsite_##_##name_##_movable_buf_compare, \
810 prisonsite_##_##name_##_movable_buf_measure},
824#define MMGR_MINIMUM_SECURITY(name_) (MinimumSecurityGuard, name_, 0)
836#define MMGR_MAXIMUM_SECURITY(name_) (MaximumSecurityGuard, name_, 1)
845#define MMGR_UNTUPLE(...) __VA_ARGS__
857#define MMGR_CARCER_APPLY(what_, prisonsite_, tuple_) MMGR_CARCER_APPLY_(what_, prisonsite_, MMGR_UNTUPLE tuple_)
870#define MMGR_CARCER_APPLY_(what_, prisonsite_, ...) what_(prisonsite_, __VA_ARGS__)
880#define MMGR_CARCER_W1(what_, prisonsite_, SeriesCellularum1_) MMGR_CARCER_APPLY(what_, prisonsite_, SeriesCellularum1_)
893#define MMGR_CARCER_W2(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_) \
894 MMGR_CARCER_W1(what_, prisonsite_, SeriesCellularum1_) \
895 MMGR_CARCER_APPLY(what_, prisonsite_, SeriesCellularum2_)
907#define MMGR_CARCER_W3(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_) \
908 MMGR_CARCER_W2(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_) \
909 MMGR_CARCER_APPLY(what_, prisonsite_, SeriesCellularum3_)
922#define MMGR_CARCER_W4(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, \
923 SeriesCellularum4_) \
924 MMGR_CARCER_W3(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_) \
925 MMGR_CARCER_APPLY(what_, prisonsite_, SeriesCellularum4_)
939#define MMGR_CARCER_W5(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, \
940 SeriesCellularum4_, SeriesCellularum5_) \
941 MMGR_CARCER_W4(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, SeriesCellularum4_) \
942 MMGR_CARCER_APPLY(what_, prisonsite_, SeriesCellularum5_)
957#define MMGR_CARCER_W6(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, \
958 SeriesCellularum4_, SeriesCellularum5_, SeriesCellularum6_) \
959 MMGR_CARCER_W5(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, SeriesCellularum4_, \
960 SeriesCellularum5_) \
961 MMGR_CARCER_APPLY(what_, prisonsite_, SeriesCellularum6_)
977#define MMGR_CARCER_W7(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, \
978 SeriesCellularum4_, SeriesCellularum5_, SeriesCellularum6_, SeriesCellularum7_) \
979 MMGR_CARCER_W6(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, SeriesCellularum4_, \
980 SeriesCellularum5_, SeriesCellularum6_) \
981 MMGR_CARCER_APPLY(what_, prisonsite_, SeriesCellularum7_)
1001#define MMGR_CARCER_W8(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, \
1002 SeriesCellularum4_, SeriesCellularum5_, SeriesCellularum6_, SeriesCellularum7_, \
1003 SeriesCellularum8_) \
1004 MMGR_CARCER_W7(what_, prisonsite_, SeriesCellularum1_, SeriesCellularum2_, SeriesCellularum3_, SeriesCellularum4_, \
1005 SeriesCellularum5_, SeriesCellularum6_, SeriesCellularum7_) \
1006 MMGR_CARCER_APPLY(what_, prisonsite_, SeriesCellularum8_)
1018#define MMGR_CARCER_WALK(what_, prisonsite_, ...) \
1019 EMBED_CAT(MMGR_CARCER_W, EMBED_NARG(__VA_ARGS__))(what_, prisonsite_, __VA_ARGS__)
1038#define LocusCarcerum(prisonsite_, ...) \
1039 MMGR_CARCER_WALK(MMGR_CARCER_BODY, prisonsite_, __VA_ARGS__) \
1040 EMBED_TABLE_STORAGE struct \
1042 MMGR_CARCER_WALK(MMGR_CARCER_MEM, prisonsite_, __VA_ARGS__) \
1043 } prisonsite_ EMBED_UNUSED = {MMGR_CARCER_WALK(MMGR_CARCER_SEAT, prisonsite_, __VA_ARGS__)}
void * mmgr_persistent_buf_alloc(SeriesCellularum *series, size_t size, const CellOwner *owner)
Takes size bytes from a cellblock's persistent tier.
static size_t mmgr_owner_hw(const CellOwner *owner)
The most payload bytes an owner has had at once.
static size_t mmgr_series_cellularum_temporary_hw(const SeriesCellularum *series)
The most bytes a cellblock's temporary tier has taken from the top.
size_t mmgr_movable_queue_depth(const SeriesCellularum *series)
The contexts queued at the cellblock's turnstiles now: those that found every open lane busy and wait...
const CarcerMovableEntry * mmgr_movable_buf_alloc(SeriesCellularum *series, size_t size, const CellOwner *owner)
Takes a persistent cell a move may move, and names it in the table.
size_t mmgr_buf_available(SeriesCellularum *series)
The bytes lying between the two tiers.
embed_bool mmgr_movable_buf_release(SeriesCellularum *series, const CarcerMovableEntry *cell, const CellOwner *owner)
Gives a movable cell back and frees its entry.
static embed_bool mmgr_series_cellularum_idle(const SeriesCellularum *series)
Whether no cell is taken from a cellblock.
void mmgr_series_cellularum_emptied(SeriesCellularum *series)
Puts a cellblock back to the state it was declared in: both tiers empty, the closed word and the turn...
void mmgr_persistent_buf_release(SeriesCellularum *series, void *prisoner, const CellOwner *owner)
Releases a prisoner, leaving the cell's bytes as they are.
embed_bool mmgr_movable_init(SeriesCellularum *series, const CarcerMovableInitCfg *args, embed_bool wipes)
Assigns a cellblock's movable option: the translation table, its claim bits, the rows of touches and ...
size_t mmgr_movable_buf_measure(const SeriesCellularum *series, const CarcerMovableCfg *args)
The bytes from args->offset of a movable cell to the next zero byte.
void * mmgr_max_security_buf_grow(SeriesCellularum *series, void *prisoner, size_t size, const CellOwner *owner)
Grows a cell in place as mmgr_buf_grow does, and zeroes the bytes the growth adds.
void mmgr_owner_bytes_given(const CellOwner *owner, size_t bytes)
Takes bytes mmgr_owner_bytes_taken counted off their owner.
void * mmgr_temporary_buf_alloc(SeriesCellularum *series, size_t size, const CellOwner *owner)
Takes size bytes from a cellblock's temporary tier.
void * mmgr_persistent_max_security_buf_alloc(SeriesCellularum *series, size_t size, const CellOwner *owner)
Takes size bytes from a maximum security cellblock's persistent tier.
void mmgr_movable_run(SeriesCellularum *series)
The mover: what the thread the program gave runs, until its thread_wait answers EMBED_FALSE.
embed_bool mmgr_owner_listed(const CellOwner *owner)
Whether an owner is one of the table's.
void mmgr_carcer_hw_misnamed(const CellOwner *named, const CellOwner *cell_owner, size_t bytes)
Told of each give or growth that names an owner other than the one the cell counts to.
embed_bool mmgr_movable_buf_write(SeriesCellularum *series, const CarcerMovableCfg *args)
Copies args->bytes from args->src to args->offset of a movable cell.
embed_iword mmgr_movable_buf_compare(const SeriesCellularum *series, const CarcerMovableCfg *args)
Orders args->bytes of a movable cell against args->src, or against another cell where args->other_cel...
#define MMGR_OWNER_PLACE_BITS
The owner word a cell carries behind its payload, one machine word laid as fields,...
embed_bool mmgr_movable_buf_read(const SeriesCellularum *series, const CarcerMovableCfg *args)
Copies args->bytes from args->offset of a movable cell to args->dst.
static size_t mmgr_series_cellularum_persistent_hw(const SeriesCellularum *series)
The furthest a cellblock's persistent tier has reached.
static size_t mmgr_owner_in_use(const CellOwner *owner)
The payload bytes of the cells an owner has now.
void mmgr_zero_buf(void *prisoner, size_t size)
Zeroes size bytes at prisoner, releasing nothing.
void * mmgr_temporary_max_security_buf_alloc(SeriesCellularum *series, size_t size, const CellOwner *owner)
Takes size bytes from a maximum security cellblock's temporary tier.
embed_bool mmgr_movable_touches(const SeriesCellularum *series, size_t at, size_t *id, size_t *touches)
One row of touches a lane, counted as passes go through it.
size_t mmgr_align_up_buf(size_t size)
Rounds size up to a whole machine word.
#define MMGR_CARCER_ALIGN
Alignment every prisoner is handed out at: one machine word, or the atomic size word's alignment wher...
static size_t mmgr_series_cellularum_temporary_top(const SeriesCellularum *series)
Offset of the lowest temporary cell.
struct CarcerMovableEntry CarcerMovableEntry
The identity a movable cell's taker holds: a const pointer to the cell's entry in the cellblock's tra...
size_t mmgr_series_cellularum_fragmentation(const SeriesCellularum *series)
A cellblock's fragmentation: the bytes its persistent tier occupies and no cell's payload holds,...
static size_t mmgr_series_cellularum_persistent_end(const SeriesCellularum *series)
Offset just past the last persistent cell.
void mmgr_owner_bytes_taken(const CellOwner *owner, size_t bytes)
Counts bytes that lie in no cellblock to an owner, as a ring's or a page's are.
void * mmgr_buf_grow(SeriesCellularum *series, void *prisoner, size_t size, const CellOwner *owner)
Grows a cell to size payload bytes in place, where it is the newest cell of its tier.
const CellOwner * mmgr_owner_of_buf(const SeriesCellularum *series, const void *prisoner)
The owner a cell counts to, read off the word behind its payload.
CellOwner mmgr_owner_table[]
The program's owner table and the owners in it, which MMGR_OWNERS defines once.
#define MMGR_CARCER_OWNERS
The most owners a program's owner table holds.
uint64_t mmgr_carcer_hw_clock_ns(void)
The library's clock in nanoseconds, which a cell's owner word carries the take on.
embed_bool mmgr_movable_buf_move(SeriesCellularum *series)
Moves one movable cell into the first free cell below it, highest cell first.
#define MMGR_CARCER_HALF_BITS
The bits each boundary has in the word that carries both, half the atomic size word,...
embed_bool mmgr_who_owns_buf(const SeriesCellularum *series, const void *at)
Whether at lies inside the cellblock's bytes.
void mmgr_persistent_max_security_buf_release(SeriesCellularum *series, void *prisoner, const CellOwner *owner)
Zeroes a cell, then releases the prisoner.
The embedded_types headers every module builds on.
#define MMGR_ALIGN_BYTES
The DMA module, reached only when MMGR_ENABLE_DMA is set.
#define MMGR_ALLOC_SIZE(arg_)
States which argument of an allocation entry gives the extent of what it returns.
Arguments for the calls that reach a movable cell's bytes, each reading the members it names.
const CarcerMovableEntry *const cell
const CarcerMovableEntry *const other_cell
const size_t other_offset
What a program gives a cellblock for the movable option, once, through its guard's movable_init.
void(*const) thread_yield(void)
embed_bool(*const) thread_wait(uint32_t milliseconds)
void(*const) thread_moving(embed_bool moving)
embed_bool(*const) thread_started(void(*run)(void *context), void *context)
size_t(*const) thread_id(void)
const size_t storage_bytes
Asserts MMGR_CARCER_ALIGN is a power of two.
embed_atomic_usize in_use
The maximum security guard over one cellblock: every release zeroes the cell first.
embed_bool(*) movable_init(const CarcerMovableInitCfg *args)
embed_iword(*) movable_buf_compare(const CarcerMovableCfg *args)
embed_bool(*) movable_buf_write(const CarcerMovableCfg *args)
embed_bool(*) who_owns_buf(const void *at)
size_t(*) buf_available(void)
embed_bool(*) movable_buf_release(const CarcerMovableEntry *cell, const CellOwner *owner)
embed_bool(*) movable_buf_read(const CarcerMovableCfg *args)
void(*) persistent_buf_release(void *prisoner, const CellOwner *owner)
size_t(*) movable_buf_measure(const CarcerMovableCfg *args)
The minimum security guard over one cellblock: a released cell keeps whatever is in it.
embed_bool(*) movable_init(const CarcerMovableInitCfg *args)
embed_bool(*) movable_buf_write(const CarcerMovableCfg *args)
void(*) persistent_buf_release(void *prisoner, const CellOwner *owner)
embed_bool(*) movable_buf_read(const CarcerMovableCfg *args)
embed_iword(*) movable_buf_compare(const CarcerMovableCfg *args)
size_t(*) movable_buf_measure(const CarcerMovableCfg *args)
embed_bool(*) movable_buf_release(const CarcerMovableEntry *cell, const CellOwner *owner)
size_t(*) buf_available(void)
embed_bool(*) who_owns_buf(const void *at)
One cellblock's state: its bytes, the two boundaries that grow toward each other, the closed word a w...
embed_atomic_uptr movable
embed_atomic_usize in_use
EmbedTurnstiles turnstiles
embed_atomic_usize persistent_overrun
embed_atomic_usize persistent_in_use
embed_atomic_usize bounds
embed_atomic_usize temporary_overrun