|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
ra8_cache_store runtime path: put / get / read / evict / pin / checkpoint (#201). More...
#include "ra8_cache_store.h"#include <stdint.h>#include <string.h>#include "lx_api.h"#include "ra8_cache_store_internal.h"#include "ra8_check.h"#include "ra8_err.h"Go to the source code of this file.
Enumerations | |
| enum | ra8_cs_rt_const_t : uint32_t { k_ra8_cs_max_run = 0xFFFFU } |
| Runtime sizing limits. More... | |
Functions | |
| static uint16_t | internal_index_used (const ra8_cache_store_t *store) |
| Count the in-use index slots. | |
| static bool | internal_run_free (const ra8_cache_store_t *store, uint32_t start, uint32_t count) |
| True when [start, start+count) overlaps no in-use entry's run. | |
| static ra8_err_t | internal_alloc_run (const ra8_cache_store_t *store, uint32_t count, uint32_t *out_start) |
First-fit a free contiguous run of count sectors in the log region. | |
| static ra8_err_t | internal_write_entry (ra8_cache_store_t *store, uint32_t start, uint32_t seq, uint32_t key, const uint8_t *data, uint32_t len, uint16_t count) |
| Write one entry: payload sectors first, then the header (atomic commit). | |
| static ra8_err_t | internal_mark_dirty (ra8_cache_store_t *store) |
| Stamp a dirty superblock before mutating (unless already dirty). | |
| static ra8_err_t | internal_checkpoint (ra8_cache_store_t *store) |
| Save the directory + a clean superblock (the checkpoint commit). | |
| static ra8_err_t | internal_put_check (const ra8_cache_store_t *store, uint32_t key, const uint8_t *data, uint32_t len, uint32_t *out_count) |
| Validate a put request and compute its run length. | |
| static ra8_err_t | internal_read_at (const ra8_cache_store_t *store, uint32_t data_start, uint64_t byte_pos, uint8_t *dst, uint32_t max, uint32_t *out_copied) |
Copy the payload slice that starts at byte_pos, within one sector. | |
| static ra8_err_t | internal_release_run (ra8_cache_store_t *store, uint32_t start, uint16_t count) |
| Release every logical sector of a run back to the free pool. | |
| ra8_err_t | ra8_cache_store_put (ra8_cache_store_t *store, uint32_t key, const uint8_t *data, uint32_t len) |
| Seal a new entry once: append data under key, atomically. | |
| ra8_err_t | ra8_cache_store_get (const ra8_cache_store_t *store, uint32_t key, ra8_cache_store_reader_t *out_reader) |
| Open a sealed entry for random reads through ra8_cache_store_read. | |
| static ra8_err_t | internal_read_stream (const ra8_cache_store_t *store, uint32_t data_start, uint32_t data_sectors, uint64_t offset, uint8_t *buf, uint32_t len) |
Stream len payload bytes at offset, sector by sector, into buf. | |
| ra8_err_t | ra8_cache_store_read (void *ctx, uint64_t offset, uint8_t *buf, uint32_t len) |
| ra8_vsource_read_fn-shaped random read over an open entry. | |
| ra8_err_t | ra8_cache_store_evict (ra8_cache_store_t *store, uint32_t key) |
| Drop an entry and reclaim its sectors (no write-back). | |
| ra8_err_t | ra8_cache_store_pin (ra8_cache_store_t *store, uint32_t key, bool pin) |
| Pin or unpin an entry (pinned entries are never evicted). | |
| ra8_err_t | ra8_cache_store_sync (ra8_cache_store_t *store) |
| Checkpoint the index to flash (directory + clean marker not set). | |
| ra8_err_t | ra8_cache_store_close (ra8_cache_store_t *store) |
| Checkpoint, set the clean-shutdown marker, and close the store. | |
Variables | |
| static const char *const | s_tag = "ra8_cache_store" |
| Module log tag. | |
ra8_cache_store runtime path: put / get / read / evict / pin / checkpoint (#201).
The steady-state operations on a mounted store. Appends are log-structured (payload sectors first, header last) so a torn put leaves a reclaimable tail, never a visible corrupt entry. Reads stream a sector at a time through the store staging buffer so a cached blob never needs full residency. Eviction only releases sectors – write-once entries are always re-derivable, so nothing is ever written back. The mount / recovery path lives in ra8_cache_store_mount.c.
Definition in file ra8_cache_store.c.
| enum ra8_cs_rt_const_t : uint32_t |
Runtime sizing limits.
| Enumerator | |
|---|---|
| k_ra8_cs_max_run | Max run length (fits ra8_cs_entry_hdr_t sector_count). |
Definition at line 40 of file ra8_cache_store.c.
|
static |
First-fit a free contiguous run of count sectors in the log region.
First-fit linear scan from log_start; bounded by the logical span (O(sectors * index_cap)).
| [in] | store | Store to allocate within. |
| [in] | count | Run length (header + payload sectors). |
| [out] | out_start | Receives the run's first sector. |
| k_ra8_ok | A free run was found. |
| k_ra8_err_null_ptr | store or out_start NULL. |
| k_ra8_err_invalid_size | count is zero. |
| k_ra8_err_no_mem | No free run of that length exists. |
out_start is writable. out_start is untouched. Definition at line 139 of file ra8_cache_store.c.
References internal_run_free(), k_ra8_err_invalid_size, k_ra8_err_no_mem, k_ra8_ok, ra8_cache_store_t::log_start, ra8_cache_store_t::logical_sectors, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by ra8_cache_store_put().
|
static |
Save the directory + a clean superblock (the checkpoint commit).
Marks the superblock dirty first so the directory is only ever rewritten while a crash would safely replay, then writes the directory and a clean superblock.
| [in,out] | store | Store to checkpoint. |
| k_ra8_ok | Checkpoint committed clean. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_hw_init_failed | LevelX write failed. |
Definition at line 261 of file ra8_cache_store.c.
References ra8_cache_store_t::flash_state, ra8_cache_store_t::inited, internal_mark_dirty(), k_ra8_cs_clean, k_ra8_ok, priv_cache_store_dir_save(), priv_cache_store_super_write(), RA8_CHECK_NULL_PTR, RA8_INTERNAL, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, and s_tag.
Referenced by ra8_cache_store_close(), and ra8_cache_store_sync().
|
static |
Count the in-use index slots.
Linear scan of the caller-owned index array counting the in-use flag.
| [in] | store | Store to scan. |
store is unusable). | 0 | No live entries, or store / its index is NULL. |
store is the store under test. store is unmodified. Definition at line 61 of file ra8_cache_store.c.
References ra8_cache_store_entry_t::flags, ra8_cache_store_t::index, ra8_cache_store_t::index_cap, k_ra8_cache_store_flag_in_use, and RA8_INTERNAL.
Referenced by internal_put_check().
|
static |
Stamp a dirty superblock before mutating (unless already dirty).
Guarantees a clean checkpoint is invalidated before any log/dir mutation, so a crash falls back to a safe log replay.
| [in,out] | store | Store to mark. |
| k_ra8_ok | Sector 0 now reflects a dirty session. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_hw_init_failed | LevelX write failed. |
Definition at line 231 of file ra8_cache_store.c.
References ra8_cache_store_t::flash_state, ra8_cache_store_t::inited, k_ra8_cs_dirty, k_ra8_ok, priv_cache_store_super_write(), RA8_CHECK_NULL_PTR, RA8_INTERNAL, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, and s_tag.
Referenced by internal_checkpoint(), ra8_cache_store_evict(), ra8_cache_store_pin(), and ra8_cache_store_put().
|
static |
Validate a put request and compute its run length.
Runs every put precondition (args, init, size, duplicate key, index and budget capacity) and returns the total run length so the caller keeps a small, single-purpose body.
| [in] | store | Store to put into. |
| [in] | key | Content key. |
| [in] | data | Payload bytes. |
| [in] | len | Payload length. |
| [out] | out_count | Receives the run length (header + payload sectors). |
| k_ra8_ok | Request is valid; *out_count set. |
| k_ra8_err_null_ptr | store or data NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_invalid_size | len zero or run longer than the header field. |
| k_ra8_err_exists | key already present (write-once). |
| k_ra8_err_no_mem | Index full or budget exhausted. |
out_count is writable. Definition at line 299 of file ra8_cache_store.c.
References ra8_cache_store_t::data_capacity, ra8_cache_store_t::index_cap, ra8_cache_store_t::inited, internal_index_used(), k_ra8_cache_store_sector_bytes, k_ra8_cs_max_run, k_ra8_err_exists, k_ra8_err_invalid_size, k_ra8_err_no_mem, k_ra8_ok, ra8_cache_store_t::live_sectors, priv_cache_store_index_find(), RA8_CHECK_NULL_PTR, RA8_INTERNAL, RA8_VALIDATE_INIT, and s_tag.
Referenced by ra8_cache_store_put().
|
static |
Copy the payload slice that starts at byte_pos, within one sector.
Reads the covering logical sector into staging and copies at most the bytes remaining in that sector, so the caller loops sector by sector.
| [in] | store | Store whose flash is read. |
| [in] | data_start | First payload logical sector of the entry. |
| [in] | byte_pos | Byte offset within the payload. |
| [out] | dst | Destination for the copied bytes. |
| [in] | max | Upper bound on bytes to copy this call. |
| [out] | out_copied | Receives the number of bytes copied (>= 1). |
| k_ra8_ok | Slice copied. |
| k_ra8_err_null_ptr | store or dst NULL. |
| k_ra8_err_hw_init_failed | LevelX read failed. |
max >= 1 and dst covers max bytes. dst content is unspecified. Definition at line 350 of file ra8_cache_store.c.
References k_ra8_cache_store_sector_bytes, k_ra8_ok, memcpy(), priv_cache_store_sector_read(), RA8_CHECK_NULL_PTR, RA8_INTERNAL, RA8_RETURN_ON_ERROR, s_tag, and ra8_cache_store_t::staging.
Referenced by internal_read_stream().
|
static |
Stream len payload bytes at offset, sector by sector, into buf.
Loops internal_read_at until len bytes are copied; the iteration count is bounded by the entry's payload-sector span plus one.
| [in] | store | Store whose flash is read. |
| [in] | data_start | First payload logical sector of the entry. |
| [in] | data_sectors | Payload sector count (the loop bound). |
| [in] | offset | Byte offset within the payload. |
| [out] | buf | Destination (len writable bytes). |
| [in] | len | Bytes to copy. |
| k_ra8_ok | All bytes copied. |
| k_ra8_err_null_ptr | store or buf NULL. |
| k_ra8_err_hw_init_failed | LevelX read failed. |
Definition at line 464 of file ra8_cache_store.c.
References internal_read_at(), k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_INTERNAL, RA8_RETURN_ON_ERROR, and s_tag.
Referenced by ra8_cache_store_read().
|
static |
Release every logical sector of a run back to the free pool.
Loops [start, start+count) through priv_cache_store_sector_release so eviction reclaims the whole entry with no write-back.
| [in,out] | store | Store whose flash is released. |
| [in] | start | First sector of the run. |
| [in] | count | Run length. |
| k_ra8_ok | Run released. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_hw_init_failed | LevelX release failed. |
Definition at line 390 of file ra8_cache_store.c.
References ra8_cache_store_t::inited, k_ra8_ok, priv_cache_store_sector_release(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, and s_tag.
Referenced by ra8_cache_store_evict().
|
static |
True when [start, start+count) overlaps no in-use entry's run.
Nested single-condition overlap test (no compound decision).
| [in] | store | Store whose live runs are checked. |
| [in] | start | Candidate run start sector. |
| [in] | count | Candidate run length. |
| true | No live entry overlaps the candidate. |
| false | Some live entry overlaps it. |
store and its index are non-NULL. store is unmodified. Definition at line 95 of file ra8_cache_store.c.
References ra8_cache_store_entry_t::flags, ra8_cache_store_t::index, ra8_cache_store_t::index_cap, k_ra8_cache_store_flag_in_use, ra8_cache_store_entry_t::sector_count, and ra8_cache_store_entry_t::start_sector.
Referenced by internal_alloc_run().
|
static |
Write one entry: payload sectors first, then the header (atomic commit).
Fills the staging buffer per payload sector, then writes the header last so its presence certifies a complete run.
| [in,out] | store | Store to append into. |
| [in] | start | Run start (header) sector. |
| [in] | seq | Append sequence number. |
| [in] | key | Content key. |
| [in] | data | Payload bytes. |
| [in] | len | Payload length. |
| [in] | count | Run length (header + payload). |
| k_ra8_ok | Entry fully written. |
| k_ra8_err_null_ptr | store or data NULL. |
| k_ra8_err_hw_init_failed | LevelX write failed mid-run. |
Definition at line 176 of file ra8_cache_store.c.
References ra8_cs_entry_hdr_t::hdr_crc, k_ra8_cache_store_sector_bytes, k_ra8_cs_entry_magic, memcpy(), memset(), priv_cache_store_crc32(), priv_cache_store_sector_write(), RA8_CHECK_NULL_PTR, RA8_INTERNAL, RA8_RETURN_ON_ERROR, s_tag, and ra8_cache_store_t::staging.
Referenced by ra8_cache_store_put().
|
nodiscard |
Checkpoint, set the clean-shutdown marker, and close the store.
Writes the directory checkpoint and stamps the clean marker so the next ra8_cache_store_init takes the fast (no-scan) mount path, then closes the LevelX partition. After this the handle must be re-init'd before reuse.
| [in,out] | store | Initialised store. |
| k_ra8_ok | Store checkpointed, marked clean, and closed. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_hw_init_failed | LevelX write/close failed. |
Definition at line 548 of file ra8_cache_store.c.
References ra8_cache_store_t::flash, ra8_cache_store_t::inited, internal_checkpoint(), k_ra8_ok, RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, and s_tag.
Referenced by cache_store_demo_run(), and internal_demo_phase_remount().
|
nodiscard |
Drop an entry and reclaim its sectors (no write-back).
Releases the entry's LevelX logical sectors (returning them to the free pool for GC) and clears its index slot. Because every cached blob is re-derivable from its SD source, nothing is ever written back on eviction – the write-once invariant makes eviction unconditionally cheap. A pinned entry is refused.
| [in,out] | store | Initialised store. |
| [in] | key | Content key to drop. |
| k_ra8_ok | Entry dropped and reclaimed. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_not_found | key is not cached. |
| k_ra8_err_busy | Entry is pinned (unpin first). |
| k_ra8_err_hw_init_failed | LevelX sector release failed. |
Definition at line 502 of file ra8_cache_store.c.
References ra8_cache_store_entry_t::flags, ra8_cache_store_t::index, ra8_cache_store_t::inited, internal_mark_dirty(), internal_release_run(), k_ra8_cache_store_flag_pinned, k_ra8_err_busy, k_ra8_err_not_found, k_ra8_ok, ra8_cache_store_t::live_sectors, priv_cache_store_index_find(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, s_tag, ra8_cache_store_entry_t::sector_count, and ra8_cache_store_entry_t::start_sector.
Referenced by internal_demo_phase_evict(), and internal_demo_phase_remount().
|
nodiscard |
Open a sealed entry for random reads through ra8_cache_store_read.
Looks key up in the index and fills out_reader so the caller can register it with ra8_vsource_add_paged(vs, ra8_cache_store_read,
out_reader, 0, out_reader->byte_len, &id). No data is copied here.
| [in] | store | Initialised store. |
| [in] | key | Content key to open. |
| [out] | out_reader | Receives the streaming handle (out-lives the vsource). |
| k_ra8_ok | Entry found; out_reader populated. |
| k_ra8_err_null_ptr | store or out_reader NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_not_found | key is not cached. |
Definition at line 424 of file ra8_cache_store.c.
References ra8_cache_store_entry_t::byte_len, ra8_cache_store_t::index, ra8_cache_store_t::inited, k_ra8_err_not_found, k_ra8_ok, priv_cache_store_index_find(), RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, s_tag, ra8_cache_store_entry_t::sector_count, and ra8_cache_store_entry_t::start_sector.
Referenced by internal_demo_get_and_verify(), internal_demo_phase_evict(), internal_demo_phase_remount(), and internal_demo_put_and_verify().
|
nodiscard |
Pin or unpin an entry (pinned entries are never evicted).
A pin marks the currently-open book's container or the shelf/library metadata as never-evict, buying fast resume without an SD-card wake. The pin state is persisted at the next ra8_cache_store_sync / ra8_cache_store_close.
| [in,out] | store | Initialised store. |
| [in] | key | Content key to (un)pin. |
| [in] | pin | True to pin, false to unpin. |
| k_ra8_ok | Pin state updated. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_not_found | key is not cached. |
pin. Definition at line 523 of file ra8_cache_store.c.
References ra8_cache_store_entry_t::flags, ra8_cache_store_t::index, ra8_cache_store_t::inited, internal_mark_dirty(), k_ra8_cache_store_flag_pinned, k_ra8_err_not_found, k_ra8_ok, pin, priv_cache_store_index_find(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, RA8_VALIDATE_INIT, and s_tag.
Referenced by internal_demo_phase_evict().
|
nodiscard |
Seal a new entry once: append data under key, atomically.
Log-structured append with no in-place-update path: the payload sectors are written first, then the entry header last, so a power loss mid-append leaves an unreferenced (reclaimable) tail rather than a visible corrupt entry. Fails if key already exists (write-once; evict first to replace) or if the overprovisioned budget cannot fit the run.
| [in,out] | store | Initialised store. |
| [in] | key | Content key (source CRC-32). |
| [in] | data | Payload bytes (len readable). |
| [in] | len | Payload length in bytes (> 0). |
| k_ra8_ok | Entry sealed and indexed. |
| k_ra8_err_null_ptr | store or data NULL. |
| k_ra8_err_invalid_size | len is zero. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_exists | key already present (write-once). |
| k_ra8_err_no_mem | Index full or budget/free-run exhausted. |
| k_ra8_err_hw_init_failed | LevelX sector write failed. |
Definition at line 407 of file ra8_cache_store.c.
References internal_alloc_run(), internal_mark_dirty(), internal_put_check(), internal_write_entry(), k_ra8_ok, ra8_cache_store_t::live_sectors, ra8_cache_store_t::next_seq, priv_cache_store_index_add(), RA8_RETURN_ON_ERROR, and s_tag.
Referenced by internal_demo_put_and_verify().
| ra8_err_t ra8_cache_store_read | ( | void * | ctx, |
| uint64_t | offset, | ||
| uint8_t * | buf, | ||
| uint32_t | len ) |
ra8_vsource_read_fn-shaped random read over an open entry.
Reads len bytes at offset from the entry's payload sectors, one LevelX logical sector at a time through the store staging buffer. Signature matches ra8_vsource_read_fn so it binds straight into ra8_vsource_add_paged.
| [in] | ctx | A ra8_cache_store_reader_t populated by ra8_cache_store_get. |
| [in] | offset | Byte offset within the payload (< byte_len). |
| [out] | buf | Destination (len writable bytes). |
| [in] | len | Bytes to read. |
| k_ra8_ok | Bytes copied. |
| k_ra8_err_null_ptr | ctx or buf NULL. |
| k_ra8_err_out_of_range | offset + len exceeds byte_len. |
| k_ra8_err_hw_init_failed | LevelX sector read failed. |
Definition at line 489 of file ra8_cache_store.c.
References ra8_cache_store_reader_t::byte_len, ra8_cache_store_reader_t::data_sectors, ra8_cache_store_reader_t::data_start, internal_read_stream(), k_ra8_err_out_of_range, RA8_CHECK_NULL_PTR, s_tag, and ra8_cache_store_reader_t::store.
Referenced by internal_demo_get_and_verify(), and internal_demo_put_and_verify().
|
nodiscard |
Checkpoint the index to flash (directory + clean marker not set).
Serialises the live index into the on-flash directory region and rewrites the superblock. Called internally by ra8_cache_store_close; exposed so a caller can periodically shorten the replay a future crash would need. The clean marker stays unset until close.
| [in,out] | store | Initialised store. |
| k_ra8_ok | Checkpoint written. |
| k_ra8_err_null_ptr | store NULL. |
| k_ra8_err_not_initialized | Store not initialised. |
| k_ra8_err_hw_init_failed | LevelX write failed. |
Definition at line 541 of file ra8_cache_store.c.
References ra8_cache_store_t::inited, internal_checkpoint(), RA8_CHECK_NULL_PTR, RA8_VALIDATE_INIT, and s_tag.
|
static |
Module log tag.
Definition at line 33 of file ra8_cache_store.c.