aboutsummaryrefslogtreecommitdiff
path: root/include/kpl/memory.h
blob: b61d861e1b58df34f8dcb4b8b48d888b76d2ea04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * KPL memory allocator
 */

typedef enum : int32_t {
    KPL_MEMORY_ALLOCATOR_MIN_SIZE_POW2          = 5,
    KPL_MEMORY_ALLOCATOR_MIN_ROUND_SIZE_POW2    = KPL_MEMORY_ALLOCATOR_MIN_SIZE_POW2 - 1,
    KPL_MEMORY_ALLOCATOR_MAX_SIZE_POW2          = 22,
    KPL_MEMORY_ALLOCATOR_SLAB_COUNT             = KPL_MEMORY_ALLOCATOR_MAX_SIZE_POW2 + 1
} kpl_memory_allocator_enum;

/*
 * Each slab is a linked list allocated with calloc and free
 * *buffer is allocated with mmap
 */
typedef struct _kpl_memory_allocator_slab {
    uint32_t buffer_size, buffer_used;
    struct _kpl_memory_allocator_slab *slab_next;
    uint8_t *buffer;
} kpl_memory_allocator_slab;

/*
 * Each group only allocates for a single power of two
 */
typedef struct {
    int32_t slab_size_pow2;
    kpl_memory_allocator_slab *slab_head, *slab_tail;
    kpl_object_queue object_pool;
} kpl_memory_allocator_slab_group;

/*
 * The allocator allocates object rounded to the next power of two
 * We first check if the pool has objects, then bump allocate off the slab *buffer
 * Each slab is only responsible for one power of two, all objects in buffer and pool are of the same size
 * The memory is allocated from buffer and returned to the pool
 * The slabs and buffers are freed and returned to the system at once on allocator free
 * The object pools are from each mapped buffer, they do not need to be freed
 */
typedef struct {
    kpl_memory_allocator_slab_group slabs[KPL_MEMORY_ALLOCATOR_SLAB_COUNT];
} kpl_memory_allocator;

/*
 * Called by owner thread
 */
void kpl_memory_allocator_init(kpl_memory_allocator *memory_allocator);

/*
 * Called by owner thread
 */
void kpl_memory_allocator_free(kpl_memory_allocator *memory_allocator);

/*
 * Only call this though kpl_thread_object_allocate
 * All allocations must extend the KPL_OBJECT_HEADER
 */
void *kpl_memory_allocator_allocate(kpl_memory_allocator *memory_allocator, int32_t size, int32_t thread_id);

/*
 * Only call this though kpl_env_object_return
 */
void kpl_memory_allocator_return(kpl_memory_allocator *memory_allocator, void *object);