Skip to content

Commit

Permalink
Merge branch 'rs/mem-pool-improvements' into next
Browse files Browse the repository at this point in the history
MemPool allocator fixes.

* rs/mem-pool-improvements:
  mem-pool: simplify alignment calculation
  mem-pool: fix big allocations
  • Loading branch information
gitster committed Dec 28, 2023
2 parents 16e6dd2 + c61740d commit aa03d94
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,7 @@ THIRD_PARTY_SOURCES += sha1collisiondetection/%
THIRD_PARTY_SOURCES += sha1dc/%

UNIT_TEST_PROGRAMS += t-basic
UNIT_TEST_PROGRAMS += t-mem-pool
UNIT_TEST_PROGRAMS += t-strbuf
UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS))
UNIT_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS))
Expand Down
10 changes: 4 additions & 6 deletions mem-pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,17 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)
struct mp_block *p = NULL;
void *r;

/* round up to a 'GIT_MAX_ALIGNMENT' alignment */
if (len & (GIT_MAX_ALIGNMENT - 1))
len += GIT_MAX_ALIGNMENT - (len & (GIT_MAX_ALIGNMENT - 1));
len = DIV_ROUND_UP(len, GIT_MAX_ALIGNMENT) * GIT_MAX_ALIGNMENT;

if (pool->mp_block &&
pool->mp_block->end - pool->mp_block->next_free >= len)
p = pool->mp_block;

if (!p) {
if (len >= (pool->block_alloc / 2))
return mem_pool_alloc_block(pool, len, pool->mp_block);

p = mem_pool_alloc_block(pool, pool->block_alloc, NULL);
p = mem_pool_alloc_block(pool, len, pool->mp_block);
else
p = mem_pool_alloc_block(pool, pool->block_alloc, NULL);
}

r = p->next_free;
Expand Down
31 changes: 31 additions & 0 deletions t/unit-tests/t-mem-pool.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "test-lib.h"
#include "mem-pool.h"

static void setup_static(void (*f)(struct mem_pool *), size_t block_alloc)
{
struct mem_pool pool = { .block_alloc = block_alloc };
f(&pool);
mem_pool_discard(&pool, 0);
}

static void t_calloc_100(struct mem_pool *pool)
{
size_t size = 100;
char *buffer = mem_pool_calloc(pool, 1, size);
for (size_t i = 0; i < size; i++)
check_int(buffer[i], ==, 0);
if (!check(pool->mp_block != NULL))
return;
check(pool->mp_block->next_free != NULL);
check(pool->mp_block->end != NULL);
}

int cmd_main(int argc, const char **argv)
{
TEST(setup_static(t_calloc_100, 1024 * 1024),
"mem_pool_calloc returns 100 zeroed bytes with big block");
TEST(setup_static(t_calloc_100, 1),
"mem_pool_calloc returns 100 zeroed bytes with tiny block");

return test_done();
}

0 comments on commit aa03d94

Please sign in to comment.