-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Ran Benita <[email protected]>
- Loading branch information
Showing
3 changed files
with
111 additions
and
0 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#include "config.h" | ||
|
||
#include <assert.h> | ||
#include <stdalign.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#include "bump.h" | ||
|
||
// Size of initial chunk. | ||
#define INITIAL_CHUNK_SIZE 4096 | ||
// Factor by which to grow chunk sizes. | ||
#define GROWTH_FACTOR 2 | ||
|
||
static struct bump_chunk dummy_chunk = { | ||
.size = 0, | ||
.ptr = 0, | ||
.prev = NULL, | ||
}; | ||
|
||
void | ||
bump_init(struct bump *bump) | ||
{ | ||
// Create the first chunk | ||
bump->current = &dummy_chunk; | ||
} | ||
|
||
void * | ||
bump_alloc(struct bump *bump, size_t size) | ||
{ | ||
assert(size <= INITIAL_CHUNK_SIZE); | ||
|
||
/* Align size to the max alignemnt. */ | ||
const size_t max_alignment = alignof(max_align_t); | ||
size = (size + max_alignment - 1) & ~(max_alignment - 1); | ||
|
||
struct bump_chunk *chunk = bump->current; | ||
|
||
/* Check if there is enough space in the current chunk. */ | ||
if ((size_t) (chunk->ptr - chunk->memory) + size > chunk->size) { | ||
/* Not enough space, create a new chunk. */ | ||
size_t new_chunk_size = chunk->size == 0 ? INITIAL_CHUNK_SIZE : chunk->size * GROWTH_FACTOR; | ||
struct bump_chunk *new_chunk = aligned_alloc(max_alignment, sizeof(*new_chunk) + new_chunk_size); | ||
if (!new_chunk) { | ||
return NULL; | ||
} | ||
new_chunk->size = new_chunk_size; | ||
new_chunk->ptr = new_chunk->memory; | ||
new_chunk->prev = chunk; | ||
|
||
bump->current = new_chunk; | ||
chunk = new_chunk; | ||
} | ||
|
||
void *ptr = chunk->ptr; | ||
chunk->ptr += size; | ||
return ptr; | ||
} | ||
|
||
char * | ||
bump_strdup(struct bump *bump, const char *s) | ||
{ | ||
size_t len = strlen(s) + 1; | ||
char *new = bump_alloc(bump, len); | ||
if (!new) { | ||
return NULL; | ||
} | ||
memcpy(new, s, len); | ||
return new; | ||
} | ||
|
||
void | ||
bump_uninit(struct bump *bump) | ||
{ | ||
struct bump_chunk *chunk = bump->current; | ||
while (chunk != &dummy_chunk) { | ||
struct bump_chunk *prev = chunk->prev; | ||
free(chunk); | ||
chunk = prev; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#pragma once | ||
|
||
#include <stddef.h> | ||
#include <stdalign.h> | ||
|
||
struct bump_chunk { | ||
// Size of the chunk. | ||
size_t size; | ||
// Next free address in memory. | ||
char *ptr; | ||
// Pointer to the previous chunk. | ||
struct bump_chunk *prev; | ||
// Pointer to the allocated memory. | ||
alignas(max_align_t) char memory[0]; | ||
}; | ||
|
||
struct bump { | ||
struct bump_chunk *current; | ||
}; | ||
|
||
void | ||
bump_init(struct bump *bump); | ||
void | ||
bump_uninit(struct bump *bump); | ||
void | ||
*bump_alloc(struct bump *bump, size_t size); | ||
char * | ||
bump_strdup(struct bump *bump, const char *s); |