Skip to content

Commit a9452da

Browse files
committed
Templated free logic and os mem handles
1 parent b8df6b0 commit a9452da

4 files changed

Lines changed: 856 additions & 20 deletions

File tree

allocators/zialloc/alloc.cpp

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "allocator.h"
44
#include "types.h"
55
#include "segments.cpp"
6+
#include "os.cpp"
7+
#include "free.cpp"
68
#include <cstddef>
79
#include <cstdint>
810
#include <cstring>
@@ -38,17 +40,46 @@ class Allocator {
3840
};
3941

4042
void* Allocator::malloc(size_t size) {
41-
// impl here using mmap, free lists, etc...
43+
// TODO:
44+
// 1. Determine size class (small / med / large / XL)
45+
// 2. Fast path: check tcache for a free chunk of this size
46+
// 3. Slow path: find a page with space via Heap -> Segment -> Page
47+
// 4. If no page has space, allocate a new segment via os::alloc_segment()
48+
// 5. Update stats (alloc_count, bytes_in_use, etc.)
49+
// 6. Return pointer to chunk data
50+
(void)size;
51+
return nullptr;
4252
}
43-
void Allocator::free(void* ptr) {
4453

54+
void Allocator::free(void* ptr) {
55+
// TODO: delegate to the free dispatch in free.cpp
56+
// zialloc::zialloc_free_dispatch(ptr);
57+
// Update stats (free_count, bytes_in_use, etc.)
58+
(void)ptr;
4559
}
46-
void* Allocator::realloc(void* ptr, size_t size) {
4760

61+
void* Allocator::realloc(void* ptr, size_t size) {
62+
// TODO:
63+
// 1. If ptr == nullptr, equivalent to malloc(size)
64+
// 2. If size == 0, equivalent to free(ptr), return nullptr
65+
// 3. Find the chunk's current size via Page::get_chunk_size()
66+
// 4. If new size fits in current chunk, return ptr as-is
67+
// 5. Otherwise: malloc(size), memcpy, free(ptr)
68+
// 6. Update stats (realloc_count)
69+
(void)ptr; (void)size;
70+
return nullptr;
4871
}
49-
// nmemb is the # of values of size `size`. So calloc(4, sizeof(int)) may produce a 16 butes chunk
50-
void* Allocator::calloc(size_t nmemb, size_t size) {
5172

73+
// nmemb is the # of values of size `size`. So calloc(4, sizeof(int)) may produce a 16 bytes chunk
74+
void* Allocator::calloc(size_t nmemb, size_t size) {
75+
// TODO:
76+
// 1. Check for overflow: nmemb * size
77+
// 2. total = nmemb * size
78+
// 3. ptr = malloc(total)
79+
// 4. memset(ptr, 0, total) — or skip if os_mmap already zeroed it
80+
// 5. return ptr
81+
(void)nmemb; (void)size;
82+
return nullptr;
5283
}
5384

5485

@@ -71,16 +102,26 @@ static bool g_initialized = false;
71102
// Statistics tracking
72103
static allocator_stats_t g_stats = {0};
73104

74-
// Round up to alignment
75-
static inline size_t align_up(size_t size, size_t alignment) {}
76-
77-
105+
// Round up to alignment — delegate to os.cpp
106+
static inline size_t align_up(size_t size, size_t alignment) {
107+
// TODO: return zialloc::os::align_up(size, alignment)
108+
// or inline: (size + alignment - 1) & ~(alignment - 1)
109+
(void)size; (void)alignment;
110+
return 0;
111+
}
78112

79-
// Get memory from OS
80-
static void *os_alloc(size_t size) {}
113+
// Get memory from OS — delegate to os.cpp
114+
static void *os_alloc(size_t size) {
115+
// TODO: return zialloc::os::alloc_segment(size)
116+
(void)size;
117+
return nullptr;
118+
}
81119

82-
// Return memory to OS
83-
static void os_free(void *ptr, size_t size) {}
120+
// Return memory to OS — delegate to os.cpp
121+
static void os_free(void *ptr, size_t size) {
122+
// TODO: zialloc::os::free_segment(ptr, size)
123+
(void)ptr; (void)size;
124+
}
84125

85126
static void *zialloc_malloc(size_t size) {
86127
return zialloc::Allocator::instance().malloc(size);
@@ -141,13 +182,46 @@ static void zialloc_print_stats(void) {
141182
printf(" munmap calls: %lu\n", (unsigned long)g_stats.munmap_count);
142183
}
143184

144-
static bool zialloc_validate_heap(void) {}
185+
static bool zialloc_validate_heap(void) {
186+
// TODO:
187+
// 1. Walk all segments via Heap::instance()
188+
// 2. For each segment, check_canary()
189+
// 3. For each page, verify used count matches bitmap popcount
190+
// 4. Return false if any inconsistency found
191+
return true;
192+
}
145193

146-
static bool zialloc_get_stats(allocator_stats_t *stats) {}
194+
static bool zialloc_get_stats(allocator_stats_t *stats) {
195+
// TODO: copy g_stats into *stats
196+
if (!stats) return false;
197+
*stats = g_stats;
198+
return true;
199+
}
147200

148-
static int zialloc_init(void) {}
201+
static int zialloc_init(void) {
202+
// TODO:
203+
// 1. If already initialized, return 0
204+
// 2. Allocate initial segments via os::alloc_segment()
205+
// (e.g. 1 small-page segment + 1 medium-page segment)
206+
// 3. Initialize Heap::instance() with the segments
207+
// 4. Initialize canaries via generate_canary()
208+
// 5. Initialize segment keys via Segment::init_key()
209+
// 6. Set g_initialized = true
210+
// 7. Return 0 on success, -1 on failure
211+
if (g_initialized) return 0;
212+
// ... your init logic here ...
213+
g_initialized = true;
214+
return 0;
215+
}
149216

150-
static void zialloc_teardown(void) {}
217+
static void zialloc_teardown(void) {
218+
// TODO:
219+
// 1. Walk all segments, munmap each via os::free_segment()
220+
// 2. Reset Heap metadata
221+
// 3. Zero out g_stats
222+
// 4. Set g_initialized = false
223+
g_initialized = false;
224+
}
151225

152226
allocator_t zialloc_allocator = {
153227
// Required functions

0 commit comments

Comments
 (0)