MT#55283 exponential increase of arena allocations

Rel: #2165

Change-Id: I3da5a0bdd95cb4a73e39d159d19310f2b9bd7ef9
pull/2157/merge
Richard Fuchs 7 days ago
parent 57ee958611
commit 40b17bd933

@ -2,7 +2,7 @@
#include "helpers.h"
#define ARENA_MIN_PIECE_LEN 4096
#define ARENA_INITIAL_PIECE_ORDER 12 // 4096
// enable to perform each allocation separately, to make debugging (valgrind...) easier
//#define ARENA_ALLOC_DEBUG
@ -15,19 +15,31 @@ struct arena_piece {
};
static struct arena_piece *arena_piece_new(size_t size, void *(*alloc_fn)(size_t)) {
static struct arena_piece *arena_piece_new(arena_t *arena, size_t size, void *(*alloc_fn)(size_t)) {
struct arena_piece *ret;
size_t alloc_size = size + sizeof(*ret) + ARENA_ALLOC_ALIGN;
static const unsigned long overhead = sizeof(*ret) + ARENA_ALLOC_ALIGN;
unsigned long needed_size = size + overhead;
#ifndef ARENA_ALLOC_DEBUG
alloc_size = MAX(alloc_size, ARENA_MIN_PIECE_LEN);
unsigned long alloc_size = 1L << arena->piece_order;
if (needed_size > alloc_size) {
arena->piece_order = LONG_BIT - __builtin_clzl(needed_size);
alloc_size = 1L << arena->piece_order;
}
arena->piece_order++; // next needed piece will be larger
#else
unsigned long alloc_size = needed_size;
#endif
ret = alloc_fn(alloc_size);
if (!ret)
return NULL;
ret->tail = ret->buf;
ret->left = alloc_size - sizeof(*ret) - ARENA_ALLOC_ALIGN;
ret->left = alloc_size - overhead;
ret->next = NULL;
return ret;
@ -36,7 +48,8 @@ static struct arena_piece *arena_piece_new(size_t size, void *(*alloc_fn)(size_t
bool arena_init(arena_t *arena, void *(*alloc_fn)(size_t), void (*free_fn)(void *)) {
arena->alloc = alloc_fn;
arena->free = free_fn;
arena->pieces = arena_piece_new(0, alloc_fn);
arena->piece_order = ARENA_INITIAL_PIECE_ORDER;
arena->pieces = arena_piece_new(arena, 0, alloc_fn);
if (!arena->pieces)
return false;
return true;
@ -55,7 +68,7 @@ void *arena_alloc(arena_t *arena, size_t size) {
if (size <= piece->left)
goto alloc;
piece = arena_piece_new(size, arena->alloc);
piece = arena_piece_new(arena, size, arena->alloc);
if (!piece)
return NULL;
piece->next = arena->pieces;

@ -17,6 +17,7 @@ struct arena {
struct arena_piece *pieces;
void *(*alloc)(size_t);
void (*free)(void *);
unsigned int piece_order;
};
typedef struct arena arena_t;

Loading…
Cancel
Save