blob: b9dc58599c9e2e1c5a4c9fb6ac41e15bd5da9c6d [file] [log] [blame]
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +01001#include "alloc.h"
2
3#include "dlog.h"
4#include "spinlock.h"
5
6static size_t alloc_base;
7static size_t alloc_limit;
8static struct spinlock alloc_lock = SPINLOCK_INIT;
9
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010010/**
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010011 * Initializes the allocator.
12 */
13void halloc_init(size_t base, size_t size)
14{
15 alloc_base = base;
16 alloc_limit = base + size;
17}
18
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010019/**
20 * Allocates the requested amount of memory. Returns NULL when there isn't
21 * enough free memory.
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010022 */
23void *halloc(size_t size)
24{
25 return halloc_aligned(size, 2 * sizeof(size_t));
26}
27
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010028/**
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010029 * Frees the provided memory.
30 *
31 * Currently unimplemented.
32 */
33void hfree(void *ptr)
34{
35 dlog("Attempted to free pointer %p\n", ptr);
36}
37
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010038/**
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010039 * Allocates the requested amount of memory, with the requested alignment.
40 *
41 * Alignment must be a power of two. Returns NULL when there isn't enough free
42 * memory.
43 */
44void *halloc_aligned(size_t size, size_t align)
45{
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010046 void *ret;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010047
48 sl_lock(&alloc_lock);
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010049 ret = halloc_aligned_nosync(size, align);
50 sl_unlock(&alloc_lock);
51
52 return ret;
53}
54
55/**
56 * Allocates the requested amount of memory, with the requested alignment, but
57 * no synchronisation with other CPUs. The caller is responsible for serialising
58 * all such calls.
59 *
60 * Alignment must be a power of two. Returns NULL when there isn't enough free
61 * memory.
62 */
63void *halloc_aligned_nosync(size_t size, size_t align)
64{
65 size_t begin;
66 size_t end;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010067
68 begin = (alloc_base + align - 1) & ~(align - 1);
69 end = begin + size;
70
71 /* Check for overflows, and that there is enough free mem. */
72 if (end > begin && begin >= alloc_base && end <= alloc_limit)
73 alloc_base = end;
74 else
75 begin = 0;
76
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010077 return (void *)begin;
78}