Skip to content

Instantly share code, notes, and snippets.

@williamcotton
Created June 14, 2023 00:13
Show Gist options
  • Save williamcotton/99ab6e8efa3c4b6c07a149d1262dfccf to your computer and use it in GitHub Desktop.
Save williamcotton/99ab6e8efa3c4b6c07a149d1262dfccf to your computer and use it in GitHub Desktop.
#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