ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_vmem.c
Go to the documentation of this file.
1
22
23#include "ra8_vmem.h"
24
25#include <stddef.h>
26#include <stdint.h>
27#include <string.h>
28
29#include "ra8_attributes.h"
30#include "ra8_check.h"
31#include "ra8_err.h"
32#include "ra8_keycache.h"
33
35static const char* const s_tag = "ra8_vmem";
36
43typedef enum : uint32_t {
44 k_vmem_hash_mul_obj = 2654435761U,
47
54typedef enum : uint8_t {
57
84RA8_INTERNAL static uint32_t internal_vmem_hash(const void* key, uint32_t key_bytes, void* ctx)
85{
86 (void)key_bytes;
87 (void)ctx;
88 const ra8_vmem_key_t* k = (const ra8_vmem_key_t*)key;
89 const uint32_t lo = (uint32_t)k->offset;
90 const uint32_t hi = (uint32_t)(k->offset >> (uint64_t)k_vmem_off_shift);
91 return (k->object_id * (uint32_t)k_vmem_hash_mul_obj) ^
92 ((lo ^ hi) * (uint32_t)k_vmem_hash_mul_page);
93}
94
123internal_vmem_fill(void* ctx, const void* key, uint8_t* cell, uint32_t cell_bytes, void* user)
124{
125 (void)user;
126 ra8_vmem_t* vm = (ra8_vmem_t*)ctx;
127 const ra8_vmem_key_t* k = (const ra8_vmem_key_t*)key;
128 return vm->cfg.loader(vm->cfg.loader_ctx, k->object_id, k->offset, cell, cell_bytes);
129}
130
132{
133 RA8_CHECK_NULL_PTR(vm, s_tag, "vm must not be nullptr");
134 RA8_CHECK_NULL_PTR(cfg, s_tag, "cfg must not be nullptr");
135 (void)memset(vm, 0, sizeof(*vm));
136 vm->cfg = *cfg;
137 ra8_keycache_cfg_t kcfg = {};
138 kcfg.cell_mem = cfg->frame_mem;
139 kcfg.cell_bytes = cfg->frame_bytes;
140 kcfg.cell_count = cfg->frame_count;
141 kcfg.key_mem = (uint8_t*)cfg->keys;
142 kcfg.key_bytes = (uint32_t)sizeof(ra8_vmem_key_t);
143 kcfg.user_mem = nullptr;
144 kcfg.user_bytes = 0U;
145 kcfg.meta = cfg->meta;
146 kcfg.buckets = cfg->buckets;
147 kcfg.bucket_count = cfg->bucket_count;
149 kcfg.render_ctx = vm;
151 kcfg.protected_pct = cfg->protected_pct;
153 kcfg.hash_ctx = nullptr;
154 const ra8_err_t err = ra8_keycache_init(&vm->kc, &kcfg);
155 if (err != k_ra8_ok) {
156 return err;
157 }
159 return k_ra8_ok;
160}
161
162ra8_err_t ra8_vmem_get(ra8_vmem_t* vm, uint32_t object_id, uint64_t offset, void** out_page)
163{
164 RA8_CHECK_NULL_PTR(vm, s_tag, "vm must not be nullptr");
165 RA8_CHECK_NULL_PTR(out_page, s_tag, "out_page must not be nullptr");
166 const uint32_t fb = vm->cfg.frame_bytes;
167 ra8_vmem_key_t k = {};
168 k.object_id = object_id;
169 k.offset = offset - (offset % (uint64_t)fb);
170 ra8_keycache_view_t v = {};
171 const ra8_err_t err = ra8_keycache_get(&vm->kc, &k, &v);
172 if (err != k_ra8_ok) {
173 return err;
174 }
175 *out_page = v.data;
176 return k_ra8_ok;
177}
178
180{
181 RA8_CHECK_NULL_PTR(vm, s_tag, "vm must not be nullptr");
182 RA8_CHECK_NULL_PTR(page, s_tag, "page must not be nullptr");
183 return ra8_keycache_put(&vm->kc, (const uint8_t*)page);
184}
185
186ra8_err_t ra8_vmem_prefetch(ra8_vmem_t* vm, uint32_t object_id, uint64_t offset)
187{
188 RA8_CHECK_NULL_PTR(vm, s_tag, "vm must not be nullptr");
189 void* page = nullptr;
190 const ra8_err_t load_err = ra8_vmem_get(vm, object_id, offset, &page);
191 if (load_err != k_ra8_ok) {
192 return load_err;
193 }
194 /* Drop the pin now: the page is resident but evictable (SLRU probationary), so
195 * a wrong read-ahead guess ages out before hot data. */
196 return ra8_vmem_put(vm, page);
197}
198
200 uint32_t* out_hits,
201 uint32_t* out_misses,
202 uint32_t* out_evictions)
203{
204 RA8_CHECK_NULL_PTR(vm, s_tag, "vm must not be nullptr");
205 if (vm->cfg.frame_mem == nullptr) {
207 }
208 return ra8_keycache_stats(&vm->kc, out_hits, out_misses, out_evictions);
209}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
The one reusable hash + pin + evict cache engine (#147, #345).
ra8_err_t ra8_keycache_get(ra8_keycache_t *kc, const void *key, ra8_keycache_view_t *out_view)
Get (and pin) the cell for key, rendering it on a miss.
ra8_err_t ra8_keycache_stats(const ra8_keycache_t *kc, uint32_t *out_hits, uint32_t *out_misses, uint32_t *out_evictions)
Report the cache hit / miss / eviction counters.
ra8_err_t ra8_keycache_init(ra8_keycache_t *kc, const ra8_keycache_cfg_t *cfg)
Initialise a cache engine over caller-supplied storage.
ra8_err_t ra8_keycache_put(ra8_keycache_t *kc, const uint8_t *data)
Release one pin on a cell previously returned by ra8_keycache_get.
@ k_ra8_keycache_evict_slru
Segmented LRU / 2Q (scan-resistant).
ra8_err_t ra8_vmem_put(ra8_vmem_t *vm, void *page)
Release one pin on a frame previously returned by ra8_vmem_get.
Definition ra8_vmem.c:179
ra8_vmem_hash_const_t
Multiplicative constants mixing the two halves of the page key.
Definition ra8_vmem.c:43
@ k_vmem_hash_mul_page
Odd multiplier mixing the offset.
Definition ra8_vmem.c:45
@ k_vmem_hash_mul_obj
Knuth multiplicative hash (object id).
Definition ra8_vmem.c:44
ra8_err_t ra8_vmem_get(ra8_vmem_t *vm, uint32_t object_id, uint64_t offset, void **out_page)
Get (and pin) the frame holding object object_id at offset.
Definition ra8_vmem.c:162
ra8_vmem_shift_const_t
Bit shift splitting a 64-bit offset into two 32-bit halves.
Definition ra8_vmem.c:54
@ k_vmem_off_shift
Shift for the high 32 bits of the offset.
Definition ra8_vmem.c:55
static uint32_t internal_vmem_hash(const void *key, uint32_t key_bytes, void *ctx)
Injected key hash: fold the (object_id, offset) page key (division-free).
Definition ra8_vmem.c:84
static ra8_err_t internal_vmem_fill(void *ctx, const void *key, uint8_t *cell, uint32_t cell_bytes, void *user)
Fill trampoline: adapt ra8_vmem_loader_fn to the keycache seam.
Definition ra8_vmem.c:123
ra8_err_t ra8_vmem_init(ra8_vmem_t *vm, const ra8_vmem_cfg_t *cfg)
Initialise a page cache over caller-supplied storage.
Definition ra8_vmem.c:131
ra8_err_t ra8_vmem_stats(const ra8_vmem_t *vm, uint32_t *out_hits, uint32_t *out_misses, uint32_t *out_evictions)
Report the cache hit / miss / eviction counters.
Definition ra8_vmem.c:199
ra8_err_t ra8_vmem_prefetch(ra8_vmem_t *vm, uint32_t object_id, uint64_t offset)
Warm the frame holding object object_id at offset into the cache without holding a pin (single-thread...
Definition ra8_vmem.c:186
Byte-range page cache with SLRU eviction (Layer 2, #147).
Caller-supplied storage + policy + renderer for ra8_keycache_init.
void * hash_ctx
Opaque context passed to hash.
uint32_t bucket_count
Number of hash buckets (>= 1).
uint32_t user_bytes
Bytes per user descriptor (may be 0).
uint8_t * cell_mem
cell_count * cell_bytes of cell storage.
uint8_t protected_pct
SLRU protected share 1..100; 0 => 75%.
uint32_t cell_bytes
Bytes per cell (the rendered payload).
uint8_t * key_mem
cell_count * key_bytes of key storage.
int32_t * buckets
bucket_count hash-bucket heads.
ra8_keycache_evict_t evict
Eviction policy (0 => LRU; SLRU opt-in).
uint32_t key_bytes
Bytes per key (>= 1).
ra8_keycache_cell_t * meta
cell_count link-metadata entries.
uint32_t cell_count
Number of cells.
void * render_ctx
Opaque context passed to render.
ra8_keycache_render_fn render
Render-on-miss callback.
uint8_t * user_mem
cell_count * user_bytes, or NULL if none.
ra8_keycache_hash_fn hash
Key hash; NULL selects built-in FNV-1a.
uint32_t protected_cap
Protected-segment capacity (0 = LRU).
A pinned view of a cached cell returned by ra8_keycache_get.
Caller-supplied storage + loader for ra8_vmem_init.
Definition ra8_vmem.h:151
uint32_t bucket_count
Number of hash buckets (>= 1).
Definition ra8_vmem.h:158
uint32_t frame_bytes
Bytes per frame (page size, e.g.
Definition ra8_vmem.h:153
ra8_vmem_frame_t * meta
frame_count metadata entries.
Definition ra8_vmem.h:155
int32_t * buckets
bucket_count hash-bucket heads.
Definition ra8_vmem.h:157
uint32_t frame_count
Number of frames.
Definition ra8_vmem.h:154
uint8_t protected_pct
SLRU protected-segment share, 1..100; 0 selects the 75% default.
Definition ra8_vmem.h:161
uint8_t * frame_mem
frame_count * frame_bytes of page storage.
Definition ra8_vmem.h:152
void * loader_ctx
Opaque context passed to loader.
Definition ra8_vmem.h:160
ra8_vmem_key_t * keys
frame_count key-storage entries.
Definition ra8_vmem.h:156
ra8_vmem_loader_fn loader
Page-fill callback (the storage DIP seam).
Definition ra8_vmem.h:159
The (object_id, frame-aligned offset) key the page cache hashes on.
Definition ra8_vmem.h:136
uint64_t offset
Frame-aligned byte offset of the cached page.
Definition ra8_vmem.h:138
uint32_t object_id
Cached object id.
Definition ra8_vmem.h:137
Page-cache state (caller-owned; treat as private).
Definition ra8_vmem.h:179
ra8_vmem_cfg_t cfg
The configuration (copied at init).
Definition ra8_vmem.h:180
ra8_keycache_t kc
The underlying SLRU cache engine.
Definition ra8_vmem.h:181
uint32_t protected_cap
Resolved SLRU protected-segment capacity.
Definition ra8_vmem.h:182