1/* @title: Memory Arenas */
2#pragma once
3#include <err.h>
4#include <mem/alloc_param.h>
5#include <mem/arena_types.h>
6#include <stddef.h>
7#include <stdint.h>
8
9/*
10 * This subsystem allows the kernel to provide generic memory arenas that
11 * explicitly declare their capabilities and accept generic parameters
12 * and have extensible extra functions, for whatever purposes they desire.
13 *
14 * Broadly, everything (or almost everything) is built with substantial
15 * room for extensibility, which allows for very different arenas that
16 * all funnel through this API, which exists to enforce safety
17 * and provide a unified substrate.
18 */
19
20struct arena;
21
22/* Errors 128+ can be used by any provider */
23enum arena_err {
24 ARENA_ERR_BUDGET = ERR_DELTA_START,
25 ARENA_ERR_ALLOC_INVALID,
26};
27
28/* arena_flags: 64 bit bitflags
29 *
30 * These flags denote the subset of globally recognized arena capabilities
31 *
32 * Upper 32 bits are available for whatever needs it in the arena
33 * allocator internally
34 *
35 * ┌─────────────────────────────────────────────────────────────┐
36 * Bits │ 63--32 31..28 27..24 23..20 19..16 15..12 11..8 7..4 3..0 │
37 * Use │ AAAA AAAA AAAA AAAA AAAA AAAA AAAA AAAA AAAA │
38 * └─────────────────────────────────────────────────────────────┘
39 *
40 * A - Unused (available)
41 * * - Unused (unavailable)
42 *
43 */
44enum arena_flags : uint64_t {
45 /* "tagging at the per-object granularity */
46 ARENA_FLAG_TAGGED = 1 << 0,
47
48 /* "stack trace at the per-object granularity" */
49 ARENA_FLAG_TRACED = 1 << 1,
50
51 /* Has a log site */
52 ARENA_FLAG_LOGGED = 1 << 2,
53
54 /* Use locks */
55 ARENA_FLAG_LOCKED = 1 << 3,
56
57 /* A reference counter is used */
58 ARENA_FLAG_REFCOUNTED = 1 << 4,
59
60 /* Protected by RCU and a defer callback */
61 ARENA_FLAG_RCU = 1 << 5,
62
63 /* Have a budget */
64 ARENA_FLAG_BUDGETED = 1 << 6,
65};
66
67/* There are 31 default arena policies (1-31, 0 is omitted
68 * to avoid uninitialized issues and bugs), and 32
69 * marks the point where anything at or greater than this
70 * is a strategy registered by other code, not by default */
71enum arena_strategy {
72 /* simple, carve out from valloc */
73 ARENA_STRATEGY_SIMPLE = 1,
74
75 /* Bump allocator */
76 ARENA_STRATEGY_BUMP,
77
78 /* All allocations are the same size,
79 * managed at initialization time */
80 ARENA_STRATEGY_FIXED,
81
82 ARENA_STRATEGY_FREELIST,
83
84 /* TODO: this should ideally reuse
85 * slab allocator code, which might
86 * mean a little porting will need to happen.
87 *
88 * Hopefully not much, since this is ideally
89 * just a wrapper around objects */
90 ARENA_STRATEGY_SLAB,
91
92 /* DIFFERENT. Notably significantly lighter-weight
93 * than the full slab allocator */
94 ARENA_STRATEGY_MINI_SLAB,
95
96 ARENA_STRATEGY_BUDDY,
97
98 /* Reserve allocators are explicitly fed memory in,
99 * so they never perform an underlying allocation operation */
100 ARENA_STRATEGY_RESERVE,
101
102 ARENA_STRATEGY_MAX = 32
103};
104
105/* These are generally passed into the arena allocation creation
106 * as a generic way of giving parameters. Notably NOT
107 * arena_attributes, as these are merely the param words.
108 *
109 * Also usable in arena_alloc_special in substitution of the size
110 * parameter, which is relevant to some allocators */
111struct arena_params {
112 void *ptr;
113 struct alloc_params alloc_params;
114
115 uint64_t params[4];
116};
117
118struct arena_attributes {
119 enum arena_flags flags;
120
121 /* For the underlying arena, to describe whatever */
122 struct arena_params params;
123};
124
125/* The output of the extended arena functions */
126struct arena_result {
127 enum err err;
128 struct arena_params params;
129};
130
131extern struct err_facility arena_err_facility;
132void arena_global_init(void);
133