My Project
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
mem_pool.cpp
Go to the documentation of this file.
1 #include "mem_pool.h"
2 
3 /*
4 // This method is currently unused
5 void MemPool::CoalesceLeft(MemBlock* b)
6 {
7  auto curPtr = b->base;
8  for (auto p = b->prev; p; p = p->prev)
9  {
10  if ((p->base + p->size) != curPtr) break;
11  curPtr = p->base;
12  p->size += b->size;
13  DelBlock(b);
14  b = p;
15  }
16 }
17 */
18 
20 {
21  auto curPtr = b->base + b->size;
22  auto next = b->next;
23  for (auto n = next; n; n = next)
24  {
25  next = n->next;
26  if (n->base != curPtr) break;
27  b->size += n->size;
28  curPtr += n->size;
29  DelBlock(n);
30  }
31 }
32 
33 bool MemPool::Allocate(MemChunk& chunk, u32 size, int align)
34 {
35  int alignM = (1 << align) - 1;
36  size = (size + alignM) &~ alignM; // Round the size
37  // Find the first suitable block
38  for (auto b = first; b; b = b->next)
39  {
40  auto addr = b->base;
41  u32 begWaste = (u32)addr & alignM;
42  addr += begWaste;
43  u32 bSize = b->size - begWaste;
44  if (bSize < size) continue;
45 
46  // Found space!
47  chunk.addr = addr;
48  chunk.size = size;
49 
50  // Resize the block
51  if (!begWaste)
52  {
53  b->base += size;
54  b->size -= size;
55  if (!b->size)
56  DelBlock(b);
57  } else
58  {
59  auto nAddr = addr + size;
60  auto nSize = bSize - size;
61  b->size = begWaste;
62  if (nSize)
63  {
64  // We need to add the tail chunk that wasn't used to the list
65  auto n = MemBlock::Create(nAddr, nSize);
66  if (n) InsertAfter(b, n);
67  else chunk.size += nSize; // we have no choice but to waste the space.
68  }
69  }
70  return true;
71  }
72 
73  return false;
74 }
75 
76 void MemPool::Deallocate(const MemChunk& chunk)
77 {
78  u8* cAddr = chunk.addr;
79  auto cSize = chunk.size;
80  bool done = false;
81 
82  // Try to merge the chunk somewhere into the list
83  for (auto b = first; !done && b; b = b->next)
84  {
85  auto addr = b->base;
86  if (addr > cAddr)
87  {
88  if ((cAddr + cSize) == addr)
89  {
90  // Merge the chunk to the left of the block
91  b->base = cAddr;
92  b->size += cSize;
93  } else
94  {
95  // We need to insert a new block
96  auto c = MemBlock::Create(cAddr, cSize);
97  if (c) InsertBefore(b, c);
98  }
99  done = true;
100  } else if ((b->base + b->size) == cAddr)
101  {
102  // Coalesce to the right
103  b->size += cSize;
104  CoalesceRight(b);
105  done = true;
106  }
107  }
108 
109  if (!done)
110  {
111  // Either the list is empty or the chunk address is past the end
112  // address of the last block -- let's add a new block at the end
113  auto b = MemBlock::Create(cAddr, cSize);
114  if (b) AddBlock(b);
115  }
116 }
117 
118 /*
119 void MemPool::Dump(const char* title)
120 {
121  printf("<%s> VRAM Pool Dump\n", title);
122  for (auto b = first; b; b = b->next)
123  printf(" - %p (%u bytes)\n", b->base, b->size);
124 }
125 */
126 
128 {
129  u32 acc = 0;
130  for (auto b = first; b; b = b->next)
131  acc += b->size;
132  return acc;
133 }
void InsertAfter(MemBlock *b, MemBlock *n)
Definition: mem_pool.h:60
u32 size
Definition: mem_pool.h:7
void CoalesceRight(MemBlock *b)
Definition: mem_pool.cpp:19
void Deallocate(const MemChunk &chunk)
Definition: mem_pool.cpp:76
uint8_t u8
Definition: types.h:21
uint32_t u32
Definition: types.h:23
u32 GetFreeSpace()
Definition: mem_pool.cpp:127
MemBlock * next
Definition: mem_pool.h:12
MemBlock * first
Definition: mem_pool.h:30
u8 * base
Definition: mem_pool.h:13
u32 size
Definition: mem_pool.h:14
void InsertBefore(MemBlock *b, MemBlock *p)
Definition: mem_pool.h:51
void DelBlock(MemBlock *b)
Definition: mem_pool.h:42
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
static MemBlock * Create(u8 *base, u32 size)
Definition: mem_pool.h:16