KernOS
memoryallocator.cpp
Go to the documentation of this file.
1 //
2 // Created on 5/26/20.
3 //
4 
5 #include <memoryallocator.h>
6 #include <interrupt.h>
7 #include <ktypes.h>
8 
9 void *kheap; // populated in boot.S
10 
11 namespace KM // kernel memory
12 {
14 
15  void MemoryAllocator::Initialize (const uint32_t StartAdd, const uint32_t EndAdd)
16  {
17  m_StartAdd = StartAdd;
18  m_EndAdd = EndAdd;
19 
20  m_Base.m_Next = (Header*) m_StartAdd;
21  m_Base.m_Size = 0;
22  m_Base.m_Next->m_Next = (Header*) m_EndAdd;
23  m_Base.m_Next->m_Size = m_EndAdd - m_StartAdd;
24  }
25 
26  void* kmalloc(size_t Size)
27  {
28  if (Size == 0)
29  kpanic("0 sized malloc requested");
30 
31  Size += sizeof(Header);
32 
33  Header* Prev = &mem_alloc.m_Base;
34  Header* Next = mem_alloc.m_Base.m_Next;
35 
36  INTRP::Mask DisableInterrupt;
37 
38  while ((uint32_t) Next != mem_alloc.m_EndAdd)
39  {
40  if (Next->m_Size == Size)
41  {
42  Prev->m_Next = Next->m_Next;
43  Prev->m_Size -= Size;
44 
45  Next->m_Next = nullptr;
46  Next->m_Size = Size;
47 
48  return (void*) (Next + 1);
49  }
50  else if (Next->m_Size > Size)
51  {
52  Header* Leftover = (Header*) ((uint32_t) Next + Size);
53  Leftover->m_Next = Next->m_Next;
54  Leftover->m_Size = Next->m_Size - Size;
55  Prev->m_Next = Leftover;
56 
57  Next->m_Next = nullptr;
58  Next->m_Size = Size;
59 
60  return (void*) (Next + 1);
61  }
62 
63  Prev = Next;
64  Next = Next->m_Next;
65  }
66 
67  kpanic("Failed to allocate memory");
68  }
69 
70  void free(void* Ptr)
71  {
72  Header* Prev = &mem_alloc.m_Base;
73  Header* Next = mem_alloc.m_Base.m_Next;
74  Header* Block = (Header*) Ptr - 1;
75  size_t Size = ((Header*) Block)->m_Size;
76 
77  INTRP::Mask DisableInterrupt;
78 
79  while ( ((uint32_t) Next != mem_alloc.m_EndAdd)
80  && (Next < Ptr)
81  )
82  {
83  Prev = Next;
84  Next = Next->m_Next;
85  }
86 
87  if (Prev == &mem_alloc.m_Base)
88  {
89  Prev->m_Next = Block;
90  Block->m_Next = Next;
91  }
92  else
93  {
94  if ((uint32_t) Prev + Prev->m_Size == (uint32_t) Block) // coalesce previous free memory if adjacent
95  {
96  Prev->m_Size += Size;
97  Block = Prev;
98  }
99 
100  if ((uint32_t) Block + Block->m_Size == (uint32_t) Next) // coalesce next free memory if adjacent
101  {
102  Block->m_Size += Next->m_Size;
103  Block->m_Next = Next->m_Next;
104  }
105  }
106  }
107 } // namespace kernel memory
108 
109 namespace INIT
110 {
114  void KMALLOC()
115  {
116  KM::mem_alloc.Initialize((uint32_t) kheap, (uint32_t)(kheap) + 4096*3);
117  }
118 }
MemoryAllocator mem_alloc
void * kmalloc(size_t Size)
kernel malloc
Header m_Base
list start
void KMALLOC()
Provides memory allocator with range of reserved memory address to manage.
Disables interrupt on construction, restores previous interrupt mask on scope exit.
Definition: interrupt.h:103
Manages kernel heap memory.
contains all kernel initialization routines
Definition: cpu.h:10
void free(void *Ptr)
kernel free
Kernel memory namespace.
uint32_t m_EndAdd
range of reserved address for kernel heap memory
void * kheap
uint32_t m_StartAdd
range of reserved address for kernel heap memory
void Initialize(const uint32_t StartAdd, const uint32_t EndAdd)
Points to range of reserved physical memory for heap allocator use.