1#include <math/units.h>
2#include <mem/elcm.h>
3#include <mem/slab.h>
4
5#include "internal.h"
6
7static bool initialized = false;
8
9static void *elcm_simple_alloc(size_t size) {
10 return simple_alloc(space: slab_global.vas, size);
11}
12
13static void elcm_simple_free(void *ptr, size_t size) {
14 simple_free(space: slab_global.vas, ptr, size);
15}
16
17struct slab_elcm_candidate slab_elcm(size_t obj_size, size_t obj_alignment) {
18 enforce_precond(obj_size && obj_alignment);
19 struct elcm_params params = {
20 .metadata_size_bytes = sizeof(struct slab),
21#ifdef DEBUG_SLAB_DEEP
22 .metadata_bits_per_obj = 1 + to_bits(sizeof(stack_handle_t)),
23#else
24 .metadata_bits_per_obj = 1,
25#endif
26
27 .obj_size = obj_size,
28 .obj_alignment = obj_alignment,
29 .bias_towards_pow2 = true,
30 .max_wastage_pct = SLAB_ELCM_DEFAULT_MAX_WASTAGE_PCT,
31 .max_pages = SLAB_MAX_PAGES,
32 .metadata_bytes_per_page = sizeof(struct page *),
33 .alloc_fn = initialized ? NULL : elcm_simple_alloc,
34 .free_fn = initialized ? NULL : elcm_simple_free,
35 };
36
37 if (elcm(params: &params) != ERR_OK)
38 return (struct slab_elcm_candidate){.pages = 0, .bitmap_size_bytes = 0};
39
40 struct elcm_candidate elc = params.out;
41
42 return (struct slab_elcm_candidate){
43 .pages = elc.pages,
44 .bitmap_size_bytes = SLAB_BITMAP_BYTES_FOR(elc.obj_count),
45 .obj_count = elc.obj_count};
46}
47
48void slab_elcm_initialize(void) {
49 initialized = true;
50}
51