tape-kernel 1.0
a modular modern independent kernel
Loading...
Searching...
No Matches
heap.c
Go to the documentation of this file.
1//alc.c - allocation and memory functions
2//upgraded to support multiple arenas
3
4#include "heap.h"
5#include "../lib/types.h"
6#include "../lib/err.h"
7
8/**
9 * @brief initializes a central heap rather then child arena
10 *
11 * hinit is a function used to initliaze a new central heap, like kheap
12 * @param arena, in hinit this is the ptr to your heap
13 * @param start, this should be a buffer like 'static uint8_t mem[HEAP_SIZE]' using the size of your heap
14 * @param size, the size of the heap using 'sizeof(mem)'
15 *
16 * using hinit is done with
17 * @code{.c}
18 * #include "../mem/heap.h" //or just heap.h
19 * #define MYHEAP_SIZE (1024 * 1024) //the size of your heap, in this case 1mb, this is in bytes, so 1024 is 1kb, 1024 * 1024 is 1mb, and etc
20 * arena_t myheap; //your heap
21 * static uint8_t mymem[MYHEAP_SIZE] //that actual size
22 * //now lets call hinit
23 * hinit(&myheap, mymem, sizeof(mymem));
24 * @endcode
25 *
26 * it initializes the heap by making the start and size be your set size but the current heap addr the start
27 *
28 * @see kheap, alc(), res(), anew(), arena_t
29*/
30void __hinit(arena_t *arena, void *start, uint32_t size) { //pointer arena is pointing to struct (check heap.h)
31 arena->start = (uint32_t*)start; //set start to start
32 arena->current = (uint32_t*)start; //make current start so it initializes
33 arena->size = size; //size to size
34}
35
36/**
37 * @brief allocates memory to a heap
38 *
39 * alc is a function that allocates memory from a central heap
40 * @param arena, the ptr to the arena to allocate from
41 * @param size, the amount to allocate
42 *
43 * using alc is done with
44 * @code{.c}
45 * #include "../mem/heap.h" //or just heap.h
46 * void* myspace = alc(&myarena, 16); //allocate 16 bytes
47 * @endcode
48 *
49 * @see res(), anew()
50*/
51void *__alc(arena_t *arena, uint32_t size) { //alc returns a void ptr to allocated mem rets 0 aka nll if alloc fails
52 assert(arena != NULL, "alc: arena is NULL"); //err handling
53 assert(arena->start != NULL, "alc: arena not initialized");
54
55 //align to four bytes
56 if (size & 3) { //if size is multiple of 4 last 2 bits set to 00 aka size & 3 = 0 then if not mult4 last 2 bits have 1s aka res is non-0
57 size = (size & (uint32_t)~3) + 4; //now round down, so we invert bits, so if res is non 0 we continue and invert them to be 1 aka align it
58 }
59
60 //get current position as byte address to avoid dumb pointer arithmetic
61 uint32_t current_addr = (uint32_t)arena->current; //save current pos's for later
62 uint32_t start_addr = (uint32_t)arena->start;
63 uint32_t end_addr = start_addr + arena->size;
64
65 //overflow check using bytes instead of pointers
66 if (current_addr + size > end_addr) { //if current + whats needed is over end then we cant allocate because were out of space
67 panic("alc: out of memory"); //alloc failed
68 }
69
70 void *ptr = (void*)current_addr; //save the address to return
71
72 arena->current = (uint32_t*)(current_addr + size); //set current to the newly allocated size using byte math
73
74 return ptr; //return the new ptr
75}
76
77/**
78 * @brief resets a arena or heap by setting current to start and overriding data
79 *
80 * @param arena, the arena or heap to reset
81*/
82void __res(arena_t *arena) {
83 arena->current = arena->start; //reset current pointer to the start of the arena
84}
85
86/**
87 * @brief creates a child arena under a central heap
88 *
89 * anew is a function that makes a child arena under a parent heap
90 * @param parent, the ptr to the parent arena
91 * @param size, the size of the arena
92 *
93 * using anew is done with
94 * @code{.c}
95 * #include "../mem/heap.h" //or just heap.h
96 * #define MYARENA_SIZE (256 * 1024) //256kb child arena
97 * arena_t *myarena
98 * myarena = anew(&myheap, MYARENA_SIZE);
99 * @endcode
100 *
101 * and you can reset this new arena or use it!
102 *
103 * @see res()
104*/
105arena_t *__anew(arena_t *parent, uint32_t size) { //anew returns a new arena allocated from parent
106 //allocate arena struct from parent
107 arena_t *new_arena = (arena_t*)alc(parent, sizeof(arena_t)); //grab space for the arena struct itself
108 assert(new_arena != NULL, "anew: failed to allocate arena struct"); //err han
109
110 //allocate memory for the new arenas buffer
111 void *buf = alc(parent, size); //grab the actual memory block for the new arena
112 assert(buf != NULL, "anew: failed to allocate arena buffer"); //err han
113
114 //initialize the new arena
115 hinit(new_arena, buf, size); //set up the new arena like a fresh heap
116
117 return new_arena; //return pointer to the new arena
118}
119
#define panic
Definition err.h:5
#define assert
Definition err.h:4
arena_t * __anew(arena_t *parent, uint32_t size)
creates a child arena under a central heap
Definition heap.c:105
void __hinit(arena_t *arena, void *start, uint32_t size)
initializes a central heap rather then child arena
Definition heap.c:30
void __res(arena_t *arena)
resets a arena or heap by setting current to start and overriding data
Definition heap.c:82
void * __alc(arena_t *arena, uint32_t size)
allocates memory to a heap
Definition heap.c:51
#define hinit
Definition heap.h:24
#define alc
Definition heap.h:25
the arena_t type
Definition heap.h:17
uint32_t * start
Definition heap.h:18
uint32_t size
Definition heap.h:20
uint32_t * current
Definition heap.h:19
#define NULL
Definition types.h:38
unsigned int uint32_t
Definition types.h:30