Created
June 14, 2023 00:13
-
-
Save williamcotton/99ab6e8efa3c4b6c07a149d1262dfccf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MEMORY_MANAGER_H | |
#define MEMORY_MANAGER_H | |
#define HEAP_SIZE (10 * 1024 * 1024) | |
#include <stdlib.h> | |
typedef struct memory_manager_malloc_t { | |
void *ptr; | |
} memory_manager_malloc_t; | |
typedef struct memory_manager_block_copy_t { | |
void *ptr; | |
} memory_manager_block_copy_t; | |
typedef void (^memoryManagerCleanupHandler)(); | |
typedef struct memory_manager_t { | |
void *freePtr; | |
void *startPtr; | |
void *endPtr; | |
} memory_manager_t; | |
void *mmMalloc(memory_manager_t *memoryManager, size_t size); | |
void *mmRealloc(memory_manager_t *memoryManager, void *ptr, size_t size); | |
void mmFree(memory_manager_t *memoryManager); | |
memory_manager_t *createMemoryManager(); | |
#endif // MEMORY_MANAGER_H | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/mman.h> | |
#include <unistd.h> | |
// Function to round given value up to nearest multiple of 8. | |
// This can be used for memory alignment purposes. | |
unsigned int roundTo8(unsigned int value) { return (value + 7) & ~7; } | |
// Custom allocation function using memory manager. | |
// It attempts to allocate a block of memory of the specified size. | |
// If the allocation is successful, the pointer to the beginning of this memory block is returned. | |
// If there's not enough space, it returns NULL. | |
void *mmMalloc(memory_manager_t *memoryManager, size_t size) { | |
void *ptr = memoryManager->freePtr; | |
memoryManager->freePtr += roundTo8(size); | |
if (memoryManager->freePtr > memoryManager->endPtr) { | |
return NULL; | |
} | |
// Initialize the allocated memory to 0 | |
memset(ptr, 0, size); | |
return ptr; | |
} | |
// Custom reallocation function using memory manager. | |
// It attempts to allocate a new block of memory of the specified size, and copies the data from the old block to the new one. | |
// If the allocation is successful, the pointer to the beginning of this new memory block is returned. | |
// If there's not enough space, it returns NULL. | |
void *mmRealloc(memory_manager_t *memoryManager, void *ptr, size_t size) { | |
void *newPtr = mmMalloc(memoryManager, size); | |
if (newPtr) { | |
memmove(newPtr, ptr, size); | |
} | |
return newPtr; | |
} | |
// Free all memory managed by a memory manager. | |
// It calls munmap to unmap the anonymous memory mapping created by mmap. | |
// After that, it frees the memory manager structure itself. | |
void mmFree(memory_manager_t *memoryManager) { | |
munmap(memoryManager->startPtr, HEAP_SIZE); | |
free(memoryManager); | |
} | |
// Function to create and initialize a memory manager. | |
// It first allocates space for a memory manager structure. | |
// Then, it creates an anonymous memory mapping which will be used for the managed memory. | |
// The start, free, and end pointers are initialized. | |
// It returns a pointer to the created memory manager. | |
memory_manager_t *createMemoryManager() { | |
memory_manager_t *memoryManager = malloc(sizeof(memory_manager_t)); | |
memoryManager->freePtr = mmap(NULL, HEAP_SIZE, PROT_READ | PROT_WRITE, | |
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | |
memoryManager->startPtr = memoryManager->freePtr; | |
memoryManager->endPtr = memoryManager->startPtr + HEAP_SIZE; | |
return memoryManager; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment