Max OS 0.3
Loading...
Searching...
No Matches
MaxOS::memory::MemoryManager Class Reference

Handles memory allocation and deallocation. More...

#include <memorymanagement.h>

Public Member Functions

 MemoryManager (VirtualMemoryManager *virtual_memory_manager=nullptr)
 Construct a new Memory Manager object. Will switch the pml4 to use the calling process's page tables.
 
 ~MemoryManager ()
 Destroy the Memory Manager object, frees the VMM if not the kernel memory manager.
 
voidhandle_malloc (size_t size)
 Allocates a block of memory.
 
void handle_free (void *pointer)
 Frees a block of memory.
 
VirtualMemoryManagervmm ()
 
size_t memory_used ()
 Returns the amount of memory used.
 

Static Public Member Functions

static voidmalloc (size_t size)
 Allocates a block of memory in the current USERSPACE heap.
 
static void free (void *pointer)
 Frees a block of memory using the current memory manager.
 
static voidkmalloc (size_t size)
 Allocates a block of memory in the KERNEL space.
 
static void kfree (void *pointer)
 Frees a block of memory using the kernel memory manager.
 
static size_t align (size_t size)
 Aligns the size to the chunk alignment.
 
static void switch_active_memory_manager (MemoryManager *manager)
 Switches the active memory manager.
 

Static Public Attributes

static MemoryManagers_current_memory_manager = nullptr
 The memory manager for the current process.
 
static MemoryManagers_kernel_memory_manager = nullptr
 The memory manager for any kernel processes and all kernel allocations.
 

Detailed Description

Handles memory allocation and deallocation.

Definition at line 40 of file memorymanagement.h.

Constructor & Destructor Documentation

◆ MemoryManager()

MemoryManager::MemoryManager ( VirtualMemoryManager vmm = nullptr)
explicit

Construct a new Memory Manager object. Will switch the pml4 to use the calling process's page tables.

Parameters
vmmThe virtual memory manager to use, if nullptr a new one will be created

Definition at line 22 of file memorymanagement.cpp.

23: m_virtual_memory_manager(vmm) {
24
25 // Create the VMM if not provided
26 if(m_virtual_memory_manager == nullptr)
27 m_virtual_memory_manager = new VirtualMemoryManager();
28
29 // Enable the memory manager
31
32 // Set up the first chunk of memory
33 this->m_first_memory_chunk = (MemoryChunk*) m_virtual_memory_manager->allocate(PAGE_SIZE + sizeof(MemoryChunk), 0);
34 m_first_memory_chunk->allocated = false;
35 m_first_memory_chunk->prev = nullptr;
36 m_first_memory_chunk->next = nullptr;
37 m_first_memory_chunk->size = PAGE_SIZE - sizeof(MemoryChunk);
38 m_last_memory_chunk = m_first_memory_chunk;
39
40 // First memory manager is the kernel memory manager
41 if(s_kernel_memory_manager == nullptr)
43
44}
static MemoryManager * s_kernel_memory_manager
The memory manager for any kernel processes and all kernel allocations.
static void switch_active_memory_manager(MemoryManager *manager)
Switches the active memory manager.
VirtualMemoryManager * vmm()
Manages the virtual memory of the system and provides functions to allocate and free memory in the vi...
Definition virtual.h:96
void * allocate(size_t size, size_t flags)
Allocate a new chunk of virtual memory.
Definition virtual.cpp:119
constexpr uint64_t PAGE_SIZE
The size of a page (4KB)
Definition physical.h:91
A span of memory in the heap, can be allocated or free. Used as a node in a doubly linked list.
MemoryChunk * prev
Pointer to the chunk before this one in the list.
MemoryChunk * next
Pointer to the chunk after this one in the list.
size_t size
The size of this span of memory (not including the MemoryChunk struct itself)
bool allocated
Whether this chunk is in use or can be allocated.

References MaxOS::memory::VirtualMemoryManager::allocate(), MaxOS::memory::MemoryChunk::allocated, MaxOS::memory::MemoryChunk::next, MaxOS::memory::PAGE_SIZE, MaxOS::memory::MemoryChunk::prev, s_kernel_memory_manager, MaxOS::memory::MemoryChunk::size, and switch_active_memory_manager().

◆ ~MemoryManager()

MemoryManager::~MemoryManager ( )

Destroy the Memory Manager object, frees the VMM if not the kernel memory manager.

Definition at line 49 of file memorymanagement.cpp.

49 {
50
51 // Free the VMM (if this is not the kernel memory manager)
52 if(m_virtual_memory_manager != nullptr && s_current_memory_manager != s_kernel_memory_manager)
53 delete m_virtual_memory_manager;
54
55 // Remove the kernel reference to this
56 if(s_kernel_memory_manager == this)
58
59 // Remove the active reference to this
60 if(s_current_memory_manager == this)
62}
static MemoryManager * s_current_memory_manager
The memory manager for the current process.

References s_current_memory_manager, and s_kernel_memory_manager.

Member Function Documentation

◆ align()

size_t MemoryManager::align ( size_t  size)
static

Aligns the size to the chunk alignment.

Parameters
sizeThe size to align
Returns
The aligned size

Definition at line 288 of file memorymanagement.cpp.

288 {
289
290 return (size / CHUNK_ALIGNMENT + 1) * CHUNK_ALIGNMENT;
291}
constexpr size_t CHUNK_ALIGNMENT
How many bytes the chunks should be a multiple of (round up to this)

References MaxOS::memory::CHUNK_ALIGNMENT.

Referenced by handle_malloc().

◆ free()

void MemoryManager::free ( void pointer)
static

Frees a block of memory using the current memory manager.

Parameters
pointerThe pointer to the block

Definition at line 158 of file memorymanagement.cpp.

158 {
159
160 // Make sure there is a memory manager
161 if(s_current_memory_manager == nullptr)
162 return;
163
164 s_current_memory_manager->handle_free(pointer);
165}

References s_current_memory_manager.

Referenced by MaxOS::system::SyscallManager::syscall_free_memory().

◆ handle_free()

void MemoryManager::handle_free ( void pointer)

Frees a block of memory.

Parameters
pointerA pointer to the block

Definition at line 186 of file memorymanagement.cpp.

186 {
187
188 // Cant free unallocated memory
189 if(pointer == nullptr)
190 return;
191
192 // Check bounds
193 if((uint64_t) pointer < (uint64_t) m_first_memory_chunk || (uint64_t) pointer > (uint64_t) m_last_memory_chunk)
194 return;
195
196 // Get the chunk information from the pointer
197 auto* chunk = (MemoryChunk*) ((size_t) pointer - sizeof(MemoryChunk));
198 chunk->allocated = false;
199
200 // If there is a free chunk before this chunk then merge them
201 if(chunk->prev != nullptr && !chunk->prev->allocated) {
202
203 // Grow the chunk behind this one so that it now contains the freed one
204 chunk->prev->size += chunk->size + sizeof(MemoryChunk);
205 chunk->prev->next = chunk->next;
206
207 // The chunk in front of the freed one now needs to point to the merged chunk
208 if(chunk->next != nullptr)
209 chunk->next->prev = chunk->prev;
210
211 // Freed chunk doesn't exist anymore so now working with the merged chunk
212 chunk = chunk->prev;
213
214 }
215
216 // If there is a free chunk after this chunk then merge them
217 if(chunk->next != nullptr && !chunk->next->allocated) {
218
219 // Grow this chunk so that it now contains the free chunk in front of the old (now freed) one
220 chunk->size += chunk->next->size + sizeof(MemoryChunk);
221
222 // Now that this chunk contains the next one, it has to point to the one in front of what has just been merged
223 // and that has to point to this
224 chunk->next = chunk->next->next;
225 if(chunk->next != nullptr)
226 chunk->next->prev = chunk;
227
228 }
229}
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22

◆ handle_malloc()

void * MemoryManager::handle_malloc ( size_t  size)

Allocates a block of memory.

Parameters
sizeThe size of the block to allocate
Returns
A pointer to the block, or nullptr if no block is available

Definition at line 100 of file memorymanagement.cpp.

100 {
101
102 MemoryChunk* result = nullptr;
103
104 // Nothing to allocate
105 if(size == 0)
106 return nullptr;
107
108 // Add room to store the chunk information
109 size = align(size + sizeof(MemoryChunk));
110
111 // Find the next free chunk that is big enough
112 for(MemoryChunk* chunk = m_first_memory_chunk; chunk != nullptr && result == nullptr; chunk = chunk->next) {
113 if(chunk->size > size && !chunk->allocated)
114 result = chunk;
115 }
116
117 // If there is no free chunk then make more room
118 if(result == nullptr)
119 result = expand_heap(size);
120
121 // If there is not left over space to store extra chunks there is no need to split the chunk
122 if(result->size < size + sizeof(MemoryChunk) + 1) {
123 result->allocated = true;
124 void* p = (void*) (((size_t) result) + sizeof(MemoryChunk));
125 return p;
126 }
127
128 // Split the chunk into: what was requested + free overflow space for future allocates
129 // - This prevents waste in the event that a big free chunk was found but the requested size would only use a portion of that
130 auto* extra = (MemoryChunk*) ((size_t) result + sizeof(MemoryChunk) + size);
131 extra->allocated = false;
132 extra->size = result->size - size - sizeof(MemoryChunk);
133 extra->prev = result;
134
135 // Add to the linked list
136 extra->next = result->next;
137 if(extra->next != nullptr)
138 extra->next->prev = extra;
139
140 // Requested chunk is now allocated exactly to the size requested and points to the free (split) block of memory that
141 // it did not use
142 result->size = size;
143 result->allocated = true;
144 result->next = extra;
145
146 // Update the last memory chunk if necessary
147 if(result == m_last_memory_chunk)
148 m_last_memory_chunk = extra;
149
150 return (void*) (((size_t) result) + sizeof(MemoryChunk));
151}
static size_t align(size_t size)
Aligns the size to the chunk alignment.

References align().

◆ kfree()

◆ kmalloc()

◆ malloc()

void * MemoryManager::malloc ( size_t  size)
static

Allocates a block of memory in the current USERSPACE heap.

Parameters
sizesize of the block
Returns
a pointer to the block, 0 if no block is available or no memory manager is set

Definition at line 70 of file memorymanagement.cpp.

70 {
71
72 // Make sure there is somthing to do the allocation
73 if(s_current_memory_manager == nullptr)
74 return nullptr;
75
76 return s_current_memory_manager->handle_malloc(size);
77}

References s_current_memory_manager.

Referenced by MaxOS::system::SyscallManager::syscall_allocate_memory(), and MaxOS::processes::Thread::Thread().

◆ memory_used()

size_t MemoryManager::memory_used ( )

Returns the amount of memory used.

Returns
The amount of memory used

Definition at line 270 of file memorymanagement.cpp.

270 {
271
272 size_t result = 0;
273
274 // Loop through all the chunks and add up the size of the allocated chunks
275 for(MemoryChunk* chunk = m_first_memory_chunk; chunk != nullptr; chunk = chunk->next)
276 if(chunk->allocated)
277 result += chunk->size;
278
279 return result;
280}

◆ switch_active_memory_manager()

void MemoryManager::switch_active_memory_manager ( MemoryManager manager)
static

Switches the active memory manager.

Parameters
managerThe new memory manager

Definition at line 299 of file memorymanagement.cpp.

299 {
300
301 // Make sure there is a manager
302 if(manager == nullptr)
303 return;
304
305 // Switch the address space
306 asm volatile("mov %0, %%cr3"::"r"((uint64_t) manager->m_virtual_memory_manager->pml4_root_address_physical()) : "memory");
307
308 // Set the active memory manager
310}

References s_current_memory_manager.

Referenced by MemoryManager().

◆ vmm()

VirtualMemoryManager * MemoryManager::vmm ( )

Gets the active virtual memory manager

Returns
The active virtual memory manager

Definition at line 317 of file memorymanagement.cpp.

317 {
318
319 return m_virtual_memory_manager;
320}

Member Data Documentation

◆ s_current_memory_manager

MemoryManager* MaxOS::memory::MemoryManager::s_current_memory_manager = nullptr
inlinestatic

The memory manager for the current process.

Definition at line 51 of file memorymanagement.h.

Referenced by free(), malloc(), switch_active_memory_manager(), and ~MemoryManager().

◆ s_kernel_memory_manager

MemoryManager* MaxOS::memory::MemoryManager::s_kernel_memory_manager = nullptr
inlinestatic

The memory manager for any kernel processes and all kernel allocations.

Definition at line 52 of file memorymanagement.h.

Referenced by kfree(), kmalloc(), MemoryManager(), MaxOS::processes::Process::Process(), MaxOS::processes::Scheduler::Scheduler(), MaxOS::memory::VirtualMemoryManager::VirtualMemoryManager(), and ~MemoryManager().


The documentation for this class was generated from the following files: