MMgr v1.0.0
Zero-heap memory manager in C11. One borrowed buffer, carved by asserted offset.
Loading...
Searching...
No Matches
confinium_externum.h
1/**
2 * @brief Placement between internal and external memory, and a two-buffer index.
3 *
4 * @warning Everything below is declared only when MMGR_ENABLE_EXTRAM is set.
5 */
6#ifndef MMGR_CONFINIUM_EXTERNUM_H
7#define MMGR_CONFINIUM_EXTERNUM_H
8
9#include "config/mmgr_config.h"
10
11#if MMGR_ENABLE_EXTRAM
12
13MMGR_INCIPE_DECLS
14
15/**
16 * @brief Where a request should be placed.
17 *
18 * @note Packed to one byte; mmgr_types.h asserts that packing reaches the compiler.
19 */
20typedef enum MMGR_ENUM_PACKED
21{
22 PLACE_DRAM = 0, /**< Internal memory. */
23 PLACE_PSRAM = 1, /**< External memory. */
24 PLACE_FAIL = 2 /**< Neither will take it. */
25} mmgr_place;
26
27/**
28 * @brief A pair of buffers, one being filled while the other is drained.
29 *
30 * @note fill_idx is the only member; the buffers it indexes are stored elsewhere.
31 */
32typedef struct
33{
34 uint8_t fill_idx; /**< Index of the buffer being filled, 0 or 1. */
35} PingPong;
36
37/**
38 * @brief Arguments for every exter call; each reads only what it needs.
39 *
40 * @note free_dram and free_psram are supplied by the caller and used as given.
41 * @note place reads the six figures; the pingpong entries read pp alone.
42 */
43typedef struct
44{
45 const size_t size; /**< Bytes to place. */
46 const mmgr_bool dma_required; /**< The bytes must be reachable by DMA. */
47 const size_t free_dram; /**< Bytes still free in internal memory. */
48 const size_t free_psram; /**< Bytes still free in external memory. */
49 const size_t psram_threshold; /**< Size at or above which external memory is tried first. */
50 const size_t dram_reserve; /**< Internal bytes that must remain free afterwards. */
51 PingPong *const pp; /**< Pair the pingpong entries act on [BORROWS]. */
53
54/**
55 * @brief Type of the exter dispatch table.
56 *
57 * @note MMGR_NS_LAYOUT asserts the five members sit at consecutive MMGR_FP_SIZE offsets, with nothing else.
58 * @note Every entry takes the same argument pack, as in carceribus and infinitas.
59 */
60typedef struct
61{
62 mmgr_place (*place)(const ExternumCfg *c); /**< Decides where a request goes. */
63 void (*pingpong_init)(const ExternumCfg *c); /**< Points the pair at buffer 0. */
64 uint8_t (*pingpong_fill)(const ExternumCfg *c); /**< Index being filled. */
65 uint8_t (*pingpong_drain)(const ExternumCfg *c); /**< Index being drained. */
66 uint8_t (*pingpong_swap)(const ExternumCfg *c); /**< Swaps the two roles. */
68MMGR_NS_LAYOUT(ConfiniumExternumNs, place, pingpong_init, pingpong_fill, pingpong_drain, pingpong_swap);
69
70/**
71 * @brief Decides whether a request belongs in internal or external memory.
72 *
73 * @param[in] c Request size, the DMA requirement and both memory figures [BORROWS].
74 * @return PLACE_DRAM, PLACE_PSRAM, or PLACE_FAIL when neither will take it.
75 * @note A size of 0 gives PLACE_FAIL.
76 * @note A DMA request only ever gives PLACE_DRAM or PLACE_FAIL, never external memory.
77 * @note At or above psram_threshold external memory is preferred, below it internal is.
78 * @warning Internal placement must also leave dram_reserve free; the external test is a size comparison alone.
79 */
80mmgr_place mmgr_exter_place(const ExternumCfg *c);
81
82/**
83 * @brief Points the pair at buffer 0.
84 *
85 * @param[in,out] c Pair to reset, as c->pp [BORROWS].
86 * @warning c->pp must not be null.
87 */
88void mmgr_pingpong_init(const ExternumCfg *c);
89
90/**
91 * @brief Returns the index of the buffer being filled.
92 *
93 * @param[in] c Pair to read, as c->pp [BORROWS].
94 * @return 0 or 1.
95 * @note Does not modify c->pp.
96 * @warning c->pp must not be null.
97 */
98uint8_t mmgr_pingpong_fill_index(const ExternumCfg *c);
99
100/**
101 * @brief Returns the index of the buffer being drained.
102 *
103 * @param[in] c Pair to read, as c->pp [BORROWS].
104 * @return The other index, 0 or 1.
105 * @note Does not modify c->pp.
106 * @warning c->pp must not be null.
107 */
108uint8_t mmgr_pingpong_drain_index(const ExternumCfg *c);
109
110/**
111 * @brief Swaps which buffer is filled and which is drained.
112 *
113 * @param[in,out] c Pair to flip, as c->pp [BORROWS].
114 * @return The index now being filled, 0 or 1.
115 * @warning c->pp must not be null.
116 */
117uint8_t mmgr_pingpong_swap(const ExternumCfg *c);
118
119/**
120 * @brief Dispatch table instance named exter.
121 *
122 * @note pingpong_fill calls mmgr_pingpong_fill_index and pingpong_drain calls mmgr_pingpong_drain_index.
123 */
124MMGR_NS ConfiniumExternumNs exter MMGR_UNUSED = {
125 .place = mmgr_exter_place,
126 .pingpong_init = mmgr_pingpong_init,
127 .pingpong_fill = mmgr_pingpong_fill_index,
128 .pingpong_drain = mmgr_pingpong_drain_index,
129 .pingpong_swap = mmgr_pingpong_swap,
130};
131
132MMGR_FINIS_DECLS
133
134#endif
135
136#endif
Type of the exter dispatch table.
uint8_t(*) pingpong_swap(const ExternumCfg *c)
mmgr_place(*) place(const ExternumCfg *c)
void(*) pingpong_init(const ExternumCfg *c)
uint8_t(*) pingpong_fill(const ExternumCfg *c)
uint8_t(*) pingpong_drain(const ExternumCfg *c)
Arguments for every exter call; each reads only what it needs.
const size_t size
const size_t free_dram
const size_t free_psram
const size_t psram_threshold
PingPong *const pp
const mmgr_bool dma_required
const size_t dram_reserve
A pair of buffers, one being filled while the other is drained.