ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
policies.c
Go to the documentation of this file.
1
18#include "cache_bench.h"
19#include "ra8_attributes.h"
20
21/* ------------------------------------------------------------------ FIFO -- */
22
46{
47 uint32_t* hand = (uint32_t*)c->policy_workspace;
48 c->policy_data = hand;
49 return (hand == nullptr) ? 1 : 0;
50}
51
68{
69 c->policy_data = nullptr;
70}
71
93static uint32_t internal_fifo_victim(cb_cache_t* c, uint32_t* scanned)
94{
95 uint32_t* hand = (uint32_t*)c->policy_data;
96 const uint32_t f = *hand;
97 *hand = (*hand + 1U) % c->capacity;
98 *scanned = 1U;
99 return f;
100}
102 .name = "FIFO",
103 .meta_bytes = 0U,
104 .state_base_bytes = sizeof(uint32_t),
105 .state_frame_bytes = 0U,
106 .init = internal_fifo_init,
107 .deinit = internal_fifo_deinit,
108 .on_access = nullptr,
109 .on_insert = nullptr,
110 .pick_victim = internal_fifo_victim,
111};
112
113/* ---------------------------------------------------------------- Random -- */
114
124typedef enum : uint64_t {
125 k_rand_seed = 0x123456789ABCDEF0ULL,
127
136typedef enum : uint8_t {
141
165{
166 uint64_t* s = (uint64_t*)c->policy_workspace;
167 if (s != nullptr) {
168 *s = (uint64_t)k_rand_seed;
169 }
170 c->policy_data = s;
171 return (s == nullptr) ? 1 : 0;
172}
173
190{
191 c->policy_data = nullptr;
192}
193
215static uint32_t internal_rand_victim(cb_cache_t* c, uint32_t* scanned)
216{
217 uint64_t* s = (uint64_t*)c->policy_data;
218 uint64_t x = *s;
219 x ^= x << (uint8_t)k_rand_shift_a;
220 x ^= x >> (uint8_t)k_rand_shift_b;
221 x ^= x << (uint8_t)k_rand_shift_c;
222 *s = x;
223 *scanned = 1U;
224 return (uint32_t)(x % (uint64_t)c->capacity);
225}
227 .name = "Random",
228 .meta_bytes = 0U,
229 .state_base_bytes = sizeof(uint64_t),
230 .state_frame_bytes = 0U,
231 .init = internal_rand_init,
232 .deinit = internal_rand_deinit,
233 .on_access = nullptr,
234 .on_insert = nullptr,
235 .pick_victim = internal_rand_victim,
236};
237
238/* ------------------------------------------------------------------- LRU -- */
239
241typedef struct {
242 int32_t* prev;
243 int32_t* next;
244 int32_t head;
245 int32_t tail;
246} cb_lru_t;
247
272{
273 const size_t required = sizeof(cb_lru_t) + ((size_t)c->capacity * 2U * sizeof(int32_t));
274 if ((c->policy_workspace == nullptr) || (c->policy_workspace_bytes < required)) {
275 return 1;
276 }
278 l->prev = (int32_t*)&l[1];
279 l->next = &l->prev[c->capacity];
280 l->head = -1;
281 l->tail = -1;
282 c->policy_data = l;
283 return 0;
284}
285
303{
304 c->policy_data = nullptr;
305}
306
325static void internal_lru_unlink(cb_lru_t* l, int32_t f)
326{
327 if (l->prev[f] != -1) {
328 l->next[l->prev[f]] = l->next[f];
329 } else if (l->head == f) {
330 l->head = l->next[f];
331 }
332 if (l->next[f] != -1) {
333 l->prev[l->next[f]] = l->prev[f];
334 } else if (l->tail == f) {
335 l->tail = l->prev[f];
336 }
337}
338
357static void internal_lru_to_head(cb_lru_t* l, int32_t f)
358{
359 l->prev[f] = -1;
360 l->next[f] = l->head;
361 if (l->head != -1) {
362 l->prev[l->head] = f;
363 }
364 l->head = f;
365 if (l->tail == -1) {
366 l->tail = f;
367 }
368}
369
388static void internal_lru_touch(cb_cache_t* c, uint32_t frame)
389{
390 cb_lru_t* l = (cb_lru_t*)c->policy_data;
391 internal_lru_unlink(l, (int32_t)frame);
392 internal_lru_to_head(l, (int32_t)frame);
393}
394
413static void internal_lru_insert(cb_cache_t* c, uint32_t frame)
414{
415 cb_lru_t* l = (cb_lru_t*)c->policy_data;
416 internal_lru_to_head(l, (int32_t)frame);
417}
418
440static uint32_t internal_lru_victim(cb_cache_t* c, uint32_t* scanned)
441{
442 cb_lru_t* l = (cb_lru_t*)c->policy_data;
443 const int32_t f = l->tail;
445 *scanned = 1U;
446 return (uint32_t)f;
447}
449 .name = "LRU",
450 .meta_bytes = 8U,
451 .state_base_bytes = sizeof(cb_lru_t),
452 .state_frame_bytes = 2U * sizeof(int32_t),
453 .init = internal_lru_init,
454 .deinit = internal_lru_deinit,
455 .on_access = internal_lru_touch,
456 .on_insert = internal_lru_insert,
457 .pick_victim = internal_lru_victim,
458};
459
460/* ----------------------------------------------------------------- CLOCK -- */
461
485{
486 uint32_t* hand = (uint32_t*)c->policy_workspace;
487 c->policy_data = hand;
488 return (hand == nullptr) ? 1 : 0;
489}
490
507{
508 c->policy_data = nullptr;
509}
510
529static void internal_clock_set(cb_cache_t* c, uint32_t frame)
530{
531 c->frames[frame].meta[0] = 1U;
532}
533
556static uint32_t internal_clock_victim(cb_cache_t* c, uint32_t* scanned)
557{
558 uint32_t* hand = (uint32_t*)c->policy_data;
559 uint32_t seen = 0U;
560 for (;;) {
561 const uint32_t f = *hand;
562 *hand = (*hand + 1U) % c->capacity;
563 seen++;
564 if (c->frames[f].meta[0] != 0U) {
565 c->frames[f].meta[0] = 0U; /* second chance */
566 } else {
567 *scanned = seen;
568 return f;
569 }
570 }
571}
573 .name = "CLOCK",
574 .meta_bytes = 1U,
575 .state_base_bytes = sizeof(uint32_t),
576 .state_frame_bytes = 0U,
577 .init = internal_clock_init,
578 .deinit = internal_clock_deinit,
579 .on_access = internal_clock_set,
580 .on_insert = internal_clock_set,
581 .pick_victim = internal_clock_victim,
582};
583
584/* -------------------------------------------------------------- registry -- */
585
594const uint32_t g_cb_policy_count = (uint32_t)(sizeof(g_cb_policies) / sizeof(g_cb_policies[0]));
Eviction-policy comparison harness for the #147 memory-hierarchy decision record: the DIP seam every ...
const cache_policy_t *const g_cb_policies[]
The registered policy table (defined in src/policies.c).
Definition policies.c:586
const cache_policy_t g_cb_policy_srrip
SRRIP: the 2-bit re-reference-interval candidate (src/policy_scanresist.c).
const cache_policy_t g_cb_policy_slru
Segmented-LRU: the scan-resistant candidate (src/policy_scanresist.c).
const uint32_t g_cb_policy_count
Number of entries in g_cb_policies.
Definition policies.c:594
static void internal_lru_to_head(cb_lru_t *l, int32_t f)
Splice frame f to the MRU (most-recently-used) head.
Definition policies.c:357
static uint32_t internal_lru_victim(cb_cache_t *c, uint32_t *scanned)
Choose the LRU victim: the frame at the list tail.
Definition policies.c:440
static void internal_lru_unlink(cb_lru_t *l, int32_t f)
Unlink frame f from the recency list.
Definition policies.c:325
static const cache_policy_t s_cb_policy_random
Definition policies.c:226
static int internal_fifo_init(cb_cache_t *c)
Bind FIFO state: a single round-robin hand over the frame ring.
Definition policies.c:45
static uint32_t internal_clock_victim(cb_cache_t *c, uint32_t *scanned)
Choose the CLOCK victim by second-chance sweep.
Definition policies.c:556
static void internal_rand_deinit(cb_cache_t *c)
Release Random-policy state (the PRNG seed).
Definition policies.c:189
static uint32_t internal_rand_victim(cb_cache_t *c, uint32_t *scanned)
Choose a uniformly random victim frame.
Definition policies.c:215
static int internal_lru_init(cb_cache_t *c)
Bind true-LRU state: a doubly-linked recency list over frames.
Definition policies.c:271
static const cache_policy_t s_cb_policy_clock
Definition policies.c:572
static void internal_fifo_deinit(cb_cache_t *c)
Release FIFO state (the insertion hand).
Definition policies.c:67
static const cache_policy_t s_cb_policy_fifo
Definition policies.c:101
cb_rand_shift_t
xorshift64 shift-amount triple used in the Random policy's PRNG step.
Definition policies.c:136
@ k_rand_shift_b
Second xorshift64 shift.
Definition policies.c:138
@ k_rand_shift_c
Third xorshift64 shift.
Definition policies.c:139
@ k_rand_shift_a
First xorshift64 shift.
Definition policies.c:137
static void internal_clock_set(cb_cache_t *c, uint32_t frame)
CLOCK reference hook: set frame's reference bit.
Definition policies.c:529
static const cache_policy_t s_cb_policy_lru
Definition policies.c:448
cb_rand_seed_t
Initial PRNG seed for the Random eviction policy.
Definition policies.c:124
@ k_rand_seed
Reproducible non-zero xorshift seed.
Definition policies.c:125
static void internal_clock_deinit(cb_cache_t *c)
Release CLOCK state (the sweep hand).
Definition policies.c:506
static void internal_lru_touch(cb_cache_t *c, uint32_t frame)
LRU hit hook: move the just-accessed frame to the MRU head.
Definition policies.c:388
static void internal_lru_deinit(cb_cache_t *c)
Release true-LRU state (control block + index arrays).
Definition policies.c:302
static void internal_lru_insert(cb_cache_t *c, uint32_t frame)
LRU insert hook: place a freshly-loaded frame at the MRU head.
Definition policies.c:413
static int internal_clock_init(cb_cache_t *c)
Bind CLOCK state: one reference bit per frame + a sweep hand.
Definition policies.c:484
static uint32_t internal_fifo_victim(cb_cache_t *c, uint32_t *scanned)
Choose the FIFO victim: the frame the hand currently points at.
Definition policies.c:93
static int internal_rand_init(cb_cache_t *c)
Bind Random-policy state: a deterministic xorshift64 seed.
Definition policies.c:164
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
The replacement-policy DIP seam (the eventual firmware Layer-2 seam).
Definition cache_bench.h:75
The fixed-capacity frame cache a policy manages.
Definition cache_bench.h:50
cb_frame_t * frames
capacity frame slots.
Definition cache_bench.h:51
size_t policy_workspace_bytes
Bytes available at the storage.
Definition cache_bench.h:55
void * policy_data
Policy-private state (rings, stacks, sketch).
Definition cache_bench.h:53
uint32_t capacity
Number of frame slots (the RAM budget knob).
Definition cache_bench.h:52
void * policy_workspace
Caller-provided policy-state storage.
Definition cache_bench.h:54
uint8_t meta[16]
Per-policy scratch (ref bits, RRPV, list links).
Definition cache_bench.h:40
LRU recency list threaded through prev/next frame-index arrays.
Definition policies.c:241
int32_t head
Most-recently-used frame, or -1.
Definition policies.c:244
int32_t * next
next[f] – frame nearer LRU, or -1.
Definition policies.c:243
int32_t tail
Least-recently-used frame (the victim).
Definition policies.c:245
int32_t * prev
prev[f] – frame nearer MRU, or -1.
Definition policies.c:242