Skip to content

Commit

Permalink
WIP: Add bump allocator
Browse files Browse the repository at this point in the history
Signed-off-by: Ran Benita <[email protected]>
  • Loading branch information
bluetech committed Jan 25, 2025
1 parent b598132 commit e928f74
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 0 deletions.
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ libxkbcommon_sources = [
'src/xkbcomp/xkbcomp-priv.h',
'src/atom.c',
'src/atom.h',
'src/bump.c',
'src/bump.h',
'src/context.c',
'src/context.h',
'src/context-priv.c',
Expand Down
81 changes: 81 additions & 0 deletions src/bump.c
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;
}
}
28 changes: 28 additions & 0 deletions src/bump.h
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);

0 comments on commit e928f74

Please sign in to comment.