DungeonCrawl
Loading...
Searching...
No Matches
memory_management.c
Go to the documentation of this file.
1
5#include "memory_management.h"
6
7#include "../logging/logger.h"
8
16 if (size < MIN_MEMORY_POOL_SIZE) {
17 //set the size to the minimum
18 size = MIN_MEMORY_POOL_SIZE;
19 }
20
21 memory_pool_t* pool = malloc(sizeof(memory_pool_t));
22 if (!pool) {
23 log_msg(ERROR, "Memory", "Failed to allocate memory for the pool base structure");
24 return NULL;
25 }
26
27 pool->memory = malloc(size);
28 if (!pool->memory) {
29 log_msg(ERROR, "Memory", "Failed to allocate memory for the pool");
30 free(pool);
31 return NULL;
32 }
33
34 pool->pool_size = size;
35 pool->first = (memory_block_t*) pool->memory;
36 pool->first->size = size - sizeof(memory_block_t);
37 pool->first->active = 0; // mark the block as free
38 pool->first->next = NULL;// no next block
39
40 return pool;
41}
42
51void* memory_pool_alloc(memory_pool_t* pool, size_t size) {
52 memory_block_t* current = pool->first;
53
54 while (current) {
55 if (!current->active && current->size >= size) {
56 // found a free block that is large enough
57
58 const size_t remaining = current->size - size;
59 if (remaining > MIN_MEMORY_BLOCK_SIZE) {
60 // remaining is large enough
61 // create a new block for the remaining memory
62 memory_block_t* new_block = (memory_block_t*) ((char*) current + sizeof(memory_block_t) + size);
63
64 new_block->size = remaining - sizeof(memory_block_t);
65 new_block->active = 0; // mark the new block as free
66 new_block->next = current->next;// link to the next block
67
68 current->size = size;// set the size of the current block
69
70 current->next = new_block;// link to the new block
71 } else {
72 log_msg(WARNING, "Memory", "No more space left in the block, using the whole block");
73 }
74
75 //the remaining memory space is too small, so the current block will be used entirely
76 current->active = 1;
77 return (void*) (current + 1);// return pointer to user data
78 }
79 current = current->next;// move to the next block
80 }
81
82 log_msg(ERROR, "Memory", "No free block found for allocation");
83 return NULL;
84}
85
94void memory_pool_free(memory_pool_t* pool, void* ptr) {
95 if (!ptr) {
96 log_msg(ERROR, "Memory", "Pointer is NULL");
97 return;
98 }
99
100 memory_block_t* block = (memory_block_t*) ptr - 1;
101 if (block < pool->first || block >= (memory_block_t*) ((char*) pool->first + pool->pool_size)) {
102 log_msg(ERROR, "Memory", "Pointer is not in the memory pool");
103 return;
104 }
105 block->active = 0;
106
107 // when needed, defragmentation of the memory blocks
108 memory_block_t* current = pool->first;
109 while (current && current->next) {
110 if (!current->active && !current->next->active) {
111 // merge with the next block
112 current->size += sizeof(memory_block_t) + current->next->size;
113 current->next = current->next->next;// link to the next block
114 } else {
115 current = current->next;// move to the next block
116 }
117 }
118}
119
121 if (!pool) {
122 log_msg(ERROR, "Memory", "Pool is NULL");
123 return;
124 }
125
126 free(pool->memory);
127 free(pool);
128 pool = NULL;
129}
void log_msg(const log_level_t level, const char *module, const char *format,...)
Logs a formatted message with a specified log level and module.
Definition logger.c:246
Header file for logging functionality of the game.
memory_pool_t * init_memory_pool(size_t size)
Initialize a memory pool of the given size.
void * memory_pool_alloc(memory_pool_t *pool, size_t size)
Allocates memory on the given memory pool.
void shutdown_memory_pool(memory_pool_t *pool)
Shuts down the memory pool.
void memory_pool_free(memory_pool_t *pool, void *ptr)
Sets the given data pointer to not active in the given memory pool.
Exposes functions for working with the memory management.