diff options
Diffstat (limited to 'mem-pool.c')
-rw-r--r-- | mem-pool.c | 52 |
1 files changed, 46 insertions, 6 deletions
@@ -4,6 +4,7 @@ #include "git-compat-util.h" #include "mem-pool.h" +#include "gettext.h" #define BLOCK_GROWTH_SIZE (1024 * 1024 - sizeof(struct mp_block)) @@ -89,9 +90,7 @@ 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) @@ -99,9 +98,9 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len) 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; @@ -109,6 +108,47 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len) return r; } +static char *mem_pool_strvfmt(struct mem_pool *pool, const char *fmt, + va_list ap) +{ + struct mp_block *block = pool->mp_block; + char *next_free = block ? block->next_free : NULL; + size_t available = block ? block->end - block->next_free : 0; + va_list cp; + int len, len2; + size_t size; + char *ret; + + va_copy(cp, ap); + len = vsnprintf(next_free, available, fmt, cp); + va_end(cp); + if (len < 0) + die(_("unable to format message: %s"), fmt); + + size = st_add(len, 1); /* 1 for NUL */ + ret = mem_pool_alloc(pool, size); + + /* Shortcut; relies on mem_pool_alloc() not touching buffer contents. */ + if (ret == next_free) + return ret; + + len2 = vsnprintf(ret, size, fmt, ap); + if (len2 != len) + BUG("your vsnprintf is broken (returns inconsistent lengths)"); + return ret; +} + +char *mem_pool_strfmt(struct mem_pool *pool, const char *fmt, ...) +{ + va_list ap; + char *ret; + + va_start(ap, fmt); + ret = mem_pool_strvfmt(pool, fmt, ap); + va_end(ap); + return ret; +} + void *mem_pool_calloc(struct mem_pool *pool, size_t count, size_t size) { size_t len = st_mult(count, size); |