My Project
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
linear.cpp
Go to the documentation of this file.
1 #include <3ds.h>
2 #include <3ds/util/rbtree.h>
3 #include "mem_pool.h"
4 
6 
7 static MemPool sLinearPool;
8 static rbtree_t sAddrMap;
9 
11 {
14 };
15 
16 #define getAddrMapNode(x) rbtree_item((x), addrMapNode, node)
17 
18 static int addrMapNodeComparator(const rbtree_node_t* _lhs, const rbtree_node_t* _rhs)
19 {
20  auto lhs = getAddrMapNode(_lhs)->chunk.addr;
21  auto rhs = getAddrMapNode(_rhs)->chunk.addr;
22  if (lhs < rhs)
23  return -1;
24  if (lhs > rhs)
25  return 1;
26  return 0;
27 }
28 
29 static void addrMapNodeDestructor(rbtree_node_t* a)
30 {
31  free(getAddrMapNode(a));
32 }
33 
34 static addrMapNode* getNode(void* addr)
35 {
36  addrMapNode n;
37  n.chunk.addr = (u8*)addr;
38  auto p = rbtree_find(&sAddrMap, &n.node);
39  return p ? getAddrMapNode(p) : nullptr;
40 }
41 
42 static addrMapNode* newNode(const MemChunk& chunk)
43 {
44  auto p = (addrMapNode*)malloc(sizeof(addrMapNode));
45  if (!p) return nullptr;
46  p->chunk = chunk;
47  return p;
48 }
49 
50 static void delNode(addrMapNode* node)
51 {
52  rbtree_remove(&sAddrMap, &node->node, addrMapNodeDestructor);
53 }
54 
55 static bool linearInit()
56 {
58  if (blk)
59  {
60  sLinearPool.AddBlock(blk);
61  rbtree_init(&sAddrMap, addrMapNodeComparator);
62  return true;
63  }
64  return false;
65 }
66 
67 void* linearMemAlign(size_t size, size_t alignment)
68 {
69  // Enforce minimum alignment
70  if (alignment < 16)
71  alignment = 16;
72 
73  // Convert alignment to shift amount
74  int shift;
75  for (shift = 4; shift < 32; shift ++)
76  {
77  if ((1U<<shift) == alignment)
78  break;
79  }
80  if (shift == 32) // Invalid alignment
81  return nullptr;
82 
83  // Initialize the pool if it is not ready
84  if (!sLinearPool.Ready() && !linearInit())
85  return nullptr;
86 
87  // Allocate the chunk
88  MemChunk chunk;
89  if (!sLinearPool.Allocate(chunk, size, shift))
90  return nullptr;
91 
92  auto node = newNode(chunk);
93  if (!node)
94  {
95  sLinearPool.Deallocate(chunk);
96  return nullptr;
97  }
98  if (rbtree_insert(&sAddrMap, &node->node));
99  return chunk.addr;
100 }
101 
102 void* linearAlloc(size_t size)
103 {
104  return linearMemAlign(size, 16);
105 }
106 
107 void* linearRealloc(void* mem, size_t size)
108 {
109  // TODO
110  return NULL;
111 }
112 
113 void linearFree(void* mem)
114 {
115  auto node = getNode(mem);
116  if (!node) return;
117 
118  // Free the chunk
119  sLinearPool.Deallocate(node->chunk);
120 
121  // Free the node
122  delNode(node);
123 }
124 
126 {
127  return sLinearPool.GetFreeSpace();
128 }
u32 __linear_heap
Definition: initSystem.c:9
MemChunk chunk
Definition: linear.cpp:13
rbtree_node_t * node
Definition: rbtree.h:45
void * linearAlloc(size_t size)
Definition: linear.cpp:102
u32 __linear_heap_size
#define getAddrMapNode(x)
Definition: linear.cpp:16
bool Ready()
Definition: mem_pool.h:32
rbtree_node_t * rbtree_find(const rbtree_t *tree, const rbtree_node_t *node)
Definition: rbtree_find.c:5
void Deallocate(const MemChunk &chunk)
Definition: mem_pool.cpp:76
uint8_t u8
Definition: types.h:21
rbtree_node_t * rbtree_insert(rbtree_t *tree, rbtree_node_t *node)
Definition: rbtree_insert.c:85
void rbtree_init(rbtree_t *tree, rbtree_node_comparator_t comparator)
Definition: rbtree_init.c:4
void linearFree(void *mem)
Definition: linear.cpp:113
rbtree_node_t * rbtree_remove(rbtree_t *tree, rbtree_node_t *node, rbtree_node_destructor_t destructor)
Definition: rbtree_remove.c:59
void * linearRealloc(void *mem, size_t size)
Definition: linear.cpp:107
uint32_t u32
Definition: types.h:23
u32 GetFreeSpace()
Definition: mem_pool.cpp:127
Definition: rbtree.h:21
rbtree_node node
Definition: linear.cpp:12
void AddBlock(MemBlock *blk)
Definition: mem_pool.h:34
bool Allocate(MemChunk &chunk, u32 size, int align)
Definition: mem_pool.cpp:33
u8 * addr
Definition: mem_pool.h:6
u32 linearSpaceFree()
Definition: linear.cpp:125
static MemBlock * Create(u8 *base, u32 size)
Definition: mem_pool.h:16
void * linearMemAlign(size_t size, size_t alignment)
Definition: linear.cpp:67