Skip to content

Commit e07a139

Browse files
committed
Replace some C-style casts, improve padding calculation
1 parent 2f9acd0 commit e07a139

File tree

2 files changed

+36
-16
lines changed

2 files changed

+36
-16
lines changed

src/erikmtalloc.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <cstdint>
22
#include <ios>
33
#include <ostream>
4+
#include <stdexcept>
45
#include <sys/mman.h>
56
#include <unistd.h>
67
#include <thread>
@@ -81,17 +82,23 @@ void tag_chunk(char *chunk, size_t aligned_size) {
8182

8283
// Align to OS page size
8384
size_t align_to_pagesize(size_t size) {
84-
return (size_t) (size + (pagesize - (size % pagesize)));
85+
return static_cast<size_t>(size + (pagesize - (size % pagesize)));
8586
}
8687

8788
// Align size to next nearest 4 byte boundary
8889
size_t align_4(size_t size) {
89-
return (size_t) (size + (4 - (size % 4)));
90+
return static_cast<size_t>(size + (4 - (size % 4)));
91+
}
92+
93+
// Return size required (rounded up to nearest 4-byte boundary) including
94+
// additional segment header/footer that will be allocated
95+
size_t get_padded_size(size_t size) {
96+
return static_cast<size_t>(align_4(size + sizeof(segment_s)*2));
9097
}
9198

9299
// Get a pointer to the first byte of the payload section
93100
// from a segment_s header
94-
void* get_payload(uintptr_t addr) {
101+
void* get_payload(uintptr_t& addr) {
95102
return reinterpret_cast<void *>(align_4(addr + sizeof(segment_s)));
96103
}
97104

@@ -105,11 +112,12 @@ void* get_header(void* ptr) {
105112
// than the chunk size, in which case, create a chunk aligned up to the nearest page
106113
// beyond the requested size.
107114
size_t add_chunk(size_t size) {
108-
size_t aligned_size;
109-
110115
// Pad to ensure there's enough room for desired allocation + headers/footers structs
111-
size_t padded_size = (sizeof(chunk_s)*4) + ((size > DEFAULT_CHUNK_SIZE) ? size : DEFAULT_CHUNK_SIZE);
112-
aligned_size = align_to_pagesize(padded_size);
116+
size_t required_size = align_to_pagesize(sizeof(chunk_s)*2) + align_to_pagesize(get_padded_size(size));
117+
118+
// If resulting size is larger than the default chunk size, increase the size of the mmap request to
119+
// the nearest pagesize boundary past the requested size
120+
size_t aligned_size = (required_size > DEFAULT_CHUNK_SIZE) ? required_size : align_to_pagesize(DEFAULT_CHUNK_SIZE);
113121

114122
debug(std::cout, "Created chunk with size:", aligned_size, "bytes");
115123

@@ -127,7 +135,7 @@ void* create_segment_in_chunk(chunk_s* chunk, size_t size) {
127135

128136
// Update total remaining contiguous space removing allocation size + header/footer padding
129137
// TODO: Align this?
130-
chunk->remaining_size = chunk->remaining_size - (size + (sizeof(segment_s)*2));
138+
chunk->remaining_size = chunk->remaining_size - get_padded_size(size);
131139
chunk->total_allocations += 1;
132140

133141
// Skip to free space pool
@@ -147,13 +155,15 @@ void* create_segment_in_chunk(chunk_s* chunk, size_t size) {
147155
// Now write a header and footer for the new segment
148156
// Add footer to end of allocation
149157
struct segment_s* footer = reinterpret_cast<segment_s*>(align_4(free_space_ptr + sizeof(segment_s) + size));
158+
debug(std::cout, "Writing segment footer at address", footer);
150159

151160
footer->next = nullptr;
152161
footer->size = size;
153162
footer->is_allocated = true;
154163
footer->is_footer = true;
155164

156165
struct segment_s* header = reinterpret_cast<segment_s*>(align_4(free_space_ptr));
166+
debug(std::cout, "Writing segment header at address", header);
157167

158168
header->next = footer;
159169
header->size = size;
@@ -231,22 +241,28 @@ void *find_segment(size_t minimum_size) {
231241
chunk_s* parent_chunk;
232242

233243
while (r) {
234-
debug(std::cout, "Checking CHUNK", r, "with size", r->allocated_size, "and remaining space", r->remaining_size);
244+
if (r->is_footer) {
245+
r = r->next;
246+
continue;
247+
}
248+
249+
debug(std::cout, "Checking CHUNK", r, "with size", r->allocated_size, "and remaining space", r->remaining_size,
250+
"for minimum required size of", minimum_size);
235251
parent_chunk = r;
236252
segment_s* segment_iter = r->next_segment;
237253

238254
while (segment_iter) {
239255
// Look for a free segment to reclaim while searching for free chunk space
240256
// If we find it, re-use instead of allocating new segments
241-
if (segment_iter->size >= (minimum_size) && segment_iter->is_allocated == false && segment_iter->is_footer == false) {
257+
if (segment_iter->size >= minimum_size && segment_iter->is_allocated == false && segment_iter->is_footer == false) {
242258
// Located an existing segment large enough for allocation and marked unallocated
243259
debug(std::cout, "Found a reusable segment in chunk (need", minimum_size, "bytes, have", segment_iter->size, "bytes available.");
244260
return reserve_segment(parent_chunk, segment_iter, minimum_size);
245261
}
246262
segment_iter = segment_iter->next;
247263
}
248264

249-
if (r->remaining_size >= (minimum_size+pagesize) && r->is_footer == false) {
265+
if (r->remaining_size >= minimum_size && r->is_footer == false) {
250266
// Unable to find an unallocated segment, allocate a new segment in chunk
251267
debug(std::cout, "Found a free MMAP chunk (need", minimum_size, "bytes, have", r->remaining_size, "bytes available.");
252268
return create_segment_in_chunk(r, minimum_size);

src/overrides.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <cstddef>
22
#include <cstdint>
3+
#include <stdexcept>
34
#include <sys/mman.h>
45
#include <type_traits>
56
#include <unistd.h>
@@ -17,25 +18,28 @@ mutex mut;
1718
// If not, mmap more memory, beyond the nearest page boundary, and add to free list
1819
void* operator new(size_t size) {
1920
debug(std::cout, "NEW: Request for:", size, "bytes");
20-
debug(std::cout, "Acquiring lock");
21+
debug(std::cout, "Acquiring lock in operator::new");
2122

2223
unique_lock<mutex> allocation_lock(mut);
2324

24-
auto ptr = get_segment(size);
25+
void* ptr = get_segment(size);
2526

26-
debug(std::cout, "Releasing lock");
27+
debug(std::cout, "Releasing lock in operator::new");
2728
allocation_lock.unlock();
2829

30+
if (!ptr) {
31+
throw std::bad_alloc();
32+
}
2933
return ptr;
3034
}
3135

3236
void operator delete(void* ptr) {
33-
debug(std::cout, "Acquiring lock");
37+
debug(std::cout, "Acquiring lock in operator::delete");
3438
unique_lock<mutex> allocation_lock(mut);
3539

3640
debug(std::cout, "Delete for ptr", ptr);
3741
free_segment(ptr);
3842

39-
debug(std::cout, "Releasing lock");
43+
debug(std::cout, "Releasing lock in operator::delete");
4044
allocation_lock.unlock();
4145
}

0 commit comments

Comments
 (0)