39typedef enum : uint32_t {
162 const size_t alignment =
alignof(max_align_t);
163 return (value + alignment - 1U) & ~(alignment - 1U);
189 void* result = &config->
workspace[*used];
214 uint32_t block_bytes,
216 uint32_t* out_buckets)
237 if ((c->
meta ==
nullptr) || (c->
keys ==
nullptr) || (c->
buckets ==
nullptr)) {
243 *out_buckets = buckets;
278 uint32_t block_bytes,
281 if ((c ==
nullptr) || (be ==
nullptr) || (be->read ==
nullptr) || (block_bytes == 0U) ||
287 uint32_t nbuckets = 0U;
303 .frame_bytes = block_bytes,
308 .bucket_count = nbuckets,
310 .loader_ctx = &c->
vs};
356 if ((c ==
nullptr) || (payload_read ==
nullptr) || (row ==
nullptr) || (wrap_bytes == 0U)) {
363 for (uint64_t i = 0U; i < n_reads; ++i) {
364 const uint64_t off = (i * req) % wrap_bytes;
365 void* page =
nullptr;
370 const uint8_t* piece = &((
const uint8_t*)page)[off % block];
372 if ((payload_read(payload_ctx, off, expected, (uint32_t)req) !=
k_ra8_ok) ||
373 (
memcmp(piece, expected, (
size_t)req) != 0)) {
381 row->
reads = n_reads;
388 row->
hits = (uint64_t)hits;
389 row->
misses = (uint64_t)miss;
398typedef enum : uint8_t {
445 uint32_t block_bytes,
450 if ((be ==
nullptr) || (payload_read ==
nullptr) || (rows ==
nullptr) || (nrows ==
nullptr) ||
451 (config ==
nullptr)) {
455 if (be->setup(be, payload_read, payload_ctx, (uint32_t)
k_cbs_blob_bytes, block_bytes, config) !=
466 const uint64_t src0 = (be->src_bytes !=
nullptr) ? *be->src_bytes : 0U;
471 const uint64_t wrap = seq ? (uint64_t)
k_cbs_blob_bytes : (uint64_t)block_bytes;
475 .block_bytes = block_bytes,
477 .backing_bytes = be->backing_bytes};
478 const int drc =
internal_drive(&c, payload_read, payload_ctx, n, wrap, row);
537 uint32_t backend_count,
543 for (uint32_t backend = 0U; (backend < backend_count) && (result == 0); ++backend) {
544 for (uint32_t size = 0U; (size < block_count) && (result == 0); ++size) {
579 uint32_t backend_count,
585 "\n## Summary (payload 8 MiB, cache budget 1 MiB, %u B reader requests)\n",
589 for (uint32_t backend = 0U; backend < backend_count; ++backend) {
593 backends[backend].name,
595 block_count) != 0) ||
599 backends[backend].name,
601 block_count) != 0)) {
610 if ((config ==
nullptr) || (config->
workspace ==
nullptr) || (config->
output ==
nullptr) ||
611 (config->
error ==
nullptr) || (config->
scratch ==
nullptr)) {
626 "payload=%u cache_budget=%u req=%u seq_passes=%u hot_reads=%u zlib_level=%d "
627 "cache=ra8_vmem(SLRU)\n\n",
638 uint32_t row_count = 0U;
639 uint32_t backend_count = 0U;
641 int rc =
internal_execute(config, &payload, backends, backend_count, rows, &row_count);
647 "sweep-block: sweep aborted (cache required=%zu supplied=%zu; "
648 "workspace required=%zu supplied=%zu)\n",
cb_io_status_t cb_sink_format(cb_sink_t *sink, const char *format,...)
Format one bounded record and publish it atomically to the sink seam.
@ k_cb_io_ok
Operation completed.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Error Code Definitions for ra8-firmware.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
void * memset(void *dst, int value, size_t n)
Fill memory with a constant byte value.
int memcmp(const void *a, const void *b, size_t n)
Compare bytes in two memory areas.
Byte-range page cache with SLRU eviction (Layer 2, #147).
ra8_err_t ra8_vmem_put(ra8_vmem_t *vm, void *page)
Release one pin on a frame previously returned by ra8_vmem_get.
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.
ra8_err_t ra8_vmem_init(ra8_vmem_t *vm, const ra8_vmem_cfg_t *cfg)
Initialise a page cache over caller-supplied storage.
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.
ra8_keycache_cell_t ra8_vmem_frame_t
Per-frame cache metadata (one caller-owned array entry per frame).
Virtual-memory object sources – the page-cache storage seam (Layer 1, #147).
ra8_err_t ra8_vsource_loader(void *ctx, uint32_t object_id, uint64_t offset, uint8_t *frame, uint32_t frame_bytes)
Fill a page frame from an object – the ra8_vmem_loader_fn adapter.
ra8_err_t ra8_vsource_add_paged(ra8_vsource_t *vs, ra8_vsource_read_fn read, void *ctx, uint64_t base, uint64_t size, uint32_t *out_id)
Register a storage-paged object; returns its object_id.
ra8_err_t(* ra8_vsource_read_fn)(void *ctx, uint64_t offset, uint8_t *buf, uint32_t len)
Read len bytes at offset from a paged object's backing.
ra8_err_t ra8_vsource_init(ra8_vsource_t *vs, ra8_vsource_obj_t *objs, uint32_t cap)
Initialise an empty source registry over a caller-owned object array.
Caller-owned bindings for the block sweep.
size_t cache_capacity
Supplied cache bytes.
cb_sink_t * error
Diagnostic destination.
size_t workspace_floor
Persistent payload-index prefix.
cb_sink_t * output
Report destination.
size_t workspace_capacity
Supplied workspace bytes.
uint8_t * workspace
Small metadata/codec-input workspace.
cb_scratch_t * scratch
Host-composed streamed RBKC transaction.
size_t workspace_used
Current phase workspace usage.
uint8_t * cache_backing
Exactly the measured resident-cache budget.
size_t workspace_required
Exact latest requirement.
size_t cache_required
Exact semantic cache requirement.
One byte-addressed backing store the sweep reads through – the backend DIP seam the #208 hardware leg...
One ra8_vmem instance sized for a swept block size + its storage.
uint32_t object_id
Registered object id.
ra8_vsource_obj_t objs[1]
The single registered object's slot.
ra8_vmem_key_t * keys
Per-frame key-storage array.
ra8_vmem_t vm
The real SLRU page cache under test.
uint32_t frames
Frame count at this block size.
int32_t * buckets
Hash-bucket heads.
ra8_vsource_t vs
Object-source registry (one object).
uint8_t * frame_mem
frames * block page storage.
cbs_meter_t meter
Vsource-seam storage-command meter.
ra8_vmem_frame_t * meta
Per-frame metadata array.
Counting shim around an ra8_vsource_read_fn.
uint64_t bytes
Bytes served through the shim.
uint64_t calls
Read calls forwarded so far.
Resettable exact pseudo-text byte source with bounded checkpoints.
One measured (backend, leg, block size) result row.
uint64_t evictions
ra8_vmem evictions.
uint64_t reads
Reader requests issued.
uint64_t wall_ns
Wall-clock time of the timed loop, in ns.
uint64_t be_calls
Backend read calls (storage commands).
uint64_t be_bytes
Bytes delivered to the cache by the backend.
uint64_t misses
ra8_vmem misses.
uint64_t hits
ra8_vmem hits.
uint64_t src_bytes
Raw medium bytes moved (compressed for RBKC).
Caller-supplied storage + loader for ra8_vmem_init.
uint32_t frame_bytes
Bytes per frame (page size, e.g.
The (object_id, frame-aligned offset) key the page cache hashes on.
Page-cache state (caller-owned; treat as private).
ra8_vmem_cfg_t cfg
The configuration (copied at init).
One registered object's backing (paged or XIP).
Object-source registry (caller-owned; treat as private).
static const uint32_t s_cbs_blocks[]
The swept block sizes, ascending (drives loops + knee search).
int cb_sweep_block(cb_sweep_config_t *config)
Run the #208 block/frame-size sweep and print the report.
static int internal_summary(cb_sweep_config_t *config, const cbs_backend_t *backends, uint32_t backend_count, const cbs_row_t *rows, uint32_t row_count)
Publish all human summary tables and the crossover verdict.
static int internal_execute(cb_sweep_config_t *config, cbs_payload_t *payload, cbs_backend_t *backends, uint32_t backend_count, cbs_row_t *rows, uint32_t *row_count)
Execute every backend and block-size pair and append its result rows.
static int internal_cache_storage(cbs_cache_t *c, uint32_t block_bytes, cb_sweep_config_t *config, uint32_t *out_buckets)
Carve and clear exact cache metadata from caller-owned bindings.
void ra8_log_emit_error(const char *tag, const char *message)
Log backend stub so ra8_check's RA8_CHECK_* macros link host-side.
static uint32_t internal_pow2_ceil(uint32_t v)
Round v up to a power of two (>= 1).
static int internal_cache_open(cbs_cache_t *c, const cbs_backend_t *be, uint32_t blob_bytes, uint32_t block_bytes, cb_sweep_config_t *config)
Stand up a real ra8_vmem cache with frame_bytes == block_bytes.
static int internal_drive(cbs_cache_t *c, ra8_vsource_read_fn payload_read, void *payload_ctx, uint64_t n_reads, uint64_t wrap_bytes, cbs_row_t *row)
Drive one timed leg: n_reads requests of k_cbs_req_bytes each, at offsets (i * req) % wrap_bytes,...
static const char *const s_cbs_leg_names[k_cbs_leg_count]
Report names for the two workload legs, indexed by cbs_leg_t.
cbs_leg_t
Leg indices for internal_run_block's per-leg loop.
@ k_cbs_leg_count
Number of legs.
@ k_cbs_leg_hot
Same-block re-read loop.
@ k_cbs_leg_seq
Sequential whole-object scan.
static void internal_cache_close(cbs_cache_t *c)
End a cbs_cache_t's borrowed workspace bindings (idempotent).
static void * internal_workspace_take(cb_sweep_config_t *config, size_t *used, size_t bytes)
Take one aligned region from the caller-owned sweep workspace.
static size_t internal_align_size(size_t value)
Round a workspace span to maximum fundamental alignment.
void ra8_log_emit_error_val(const char *tag, const char *message, uint32_t value)
Valued log backend stub (present for the linker, as reader_vmem).
cbs_block_size_t
The swept block / frame / chunk sizes, in bytes.
@ k_cbs_block_256kib
256 KiB (frame RAM gets expensive).
@ k_cbs_block_4kib
Classic VM page size.
@ k_cbs_block_16kib
16 KiB.
@ k_cbs_block_512b
One SD sector.
@ k_cbs_block_64kib
The current .rabook chunk default.
static int internal_run_block(cbs_backend_t *be, ra8_vsource_read_fn payload_read, void *payload_ctx, uint32_t block_bytes, cbs_row_t *rows, uint32_t *nrows, cb_sweep_config_t *config)
Run both legs of one (backend, block size) combination.
#208 block/frame-size sweep: the byte-size axis the capacity sweep never touches, so the chunked ....
Module-private seams shared by the #208 sweep translation units.
ra8_err_t priv_meter_read(void *ctx, uint64_t offset, uint8_t *buf, uint32_t len)
ra8_vsource_read_fn forwarding through a cbs_meter_t.
int priv_print_hot_table(cb_sink_t *sink, const cbs_row_t *rows, uint32_t nrows, const char *be, const uint32_t *blocks, uint32_t nblocks)
Print one backend's same-block re-read summary table (leg b).
@ k_cbs_hot_reads
Accesses in the same-block re-read leg.
@ k_cbs_bucket_min
Minimum hash-bucket count for tiny caches.
@ k_cbs_cache_bytes
1 MiB resident cache budget (constant).
@ k_cbs_seq_passes
Whole-object passes in the seq leg.
@ k_cbs_blob_bytes
8 MiB payload (2^23; all sizes divide it).
@ k_cbs_max_rows
2 backends x 6 sizes x 2 legs.
@ k_cbs_req_bytes
Reader request grain (divides every size).
int priv_payload_init(cbs_payload_t *payload, void *workspace, size_t capacity)
Build the payload source index into caller-owned storage.
int priv_print_crossover(cb_sink_t *sink, const cbs_row_t *rows, uint32_t nrows, const uint32_t *blocks, uint32_t nblocks)
Name the measured crossover and print the chunk-size recommendation.
int priv_print_row(cb_sink_t *sink, const cbs_row_t *r)
Print one machine-parseable result row (sweep-block key=value ...).
int priv_print_seq_table(cb_sink_t *sink, const cbs_row_t *rows, uint32_t nrows, const char *be, const uint32_t *blocks, uint32_t nblocks)
Print one backend's sequential-scan summary table (leg a).
ra8_err_t priv_payload_read(void *ctx, uint64_t offset, uint8_t *buffer, uint32_t length)
Read exact historical pseudo-text bytes at any bounded offset.
cbs_backend_t * priv_backends(uint32_t *out_count)
Expose the registered sweep backends (the seam the HW leg extends).
size_t priv_payload_workspace_required(void)
Return exact workspace bytes required by the pseudo-text source index.
uint64_t priv_now_ns(void)
Monotonic wall-clock in nanoseconds.