mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Add isc_mem_reget() function to realloc isc_mem_get allocations
The isc_mem_get() and isc_mem_put() functions are leaving the memory allocation size tracking to the users of the API, while isc_mem_allocate() and isc_mem_free() would track the sizes internally. This allowed to have isc_mem_rellocate() to manipulate the memory allocations by the later set, but not the former set of the functions. This commit introduces isc_mem_reget(ctx, old_ptr, old_size, new_size) function that operates on the memory allocations with external size tracking completing the API.
This commit is contained in:
parent
c5c6a76e8c
commit
aeb3d1cab3
3 changed files with 92 additions and 11 deletions
|
|
@ -134,7 +134,9 @@ extern unsigned int isc_mem_defaultflags;
|
|||
#define ISCMEMFUNC(sfx) isc__mem_##sfx
|
||||
#define ISCMEMPOOLFUNC(sfx) isc__mempool_##sfx
|
||||
|
||||
#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s)_ISC_MEM_FILELINE)
|
||||
#define isc_mem_get(c, s) ISCMEMFUNC(get)((c), (s)_ISC_MEM_FILELINE)
|
||||
#define isc_mem_reget(c, p, o, n) \
|
||||
ISCMEMFUNC(reget)((c), (p), (o), (n)_ISC_MEM_FILELINE)
|
||||
#define isc_mem_allocate(c, s) ISCMEMFUNC(allocate)((c), (s)_ISC_MEM_FILELINE)
|
||||
#define isc_mem_reallocate(c, p, s) \
|
||||
ISCMEMFUNC(reallocate)((c), (p), (s)_ISC_MEM_FILELINE)
|
||||
|
|
@ -483,6 +485,9 @@ void ISCMEMFUNC(free)(isc_mem_t *, void *_ISC_MEM_FLARG);
|
|||
ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(put), 2)
|
||||
void *ISCMEMFUNC(get)(isc_mem_t *, size_t _ISC_MEM_FLARG);
|
||||
|
||||
ISC_ATTR_DEALLOCATOR_IDX(ISCMEMFUNC(put), 2)
|
||||
void *ISCMEMFUNC(reget)(isc_mem_t *, void *, size_t, size_t _ISC_MEM_FLARG);
|
||||
|
||||
ISC_ATTR_MALLOC_DEALLOCATOR_IDX(ISCMEMFUNC(free), 2)
|
||||
void *ISCMEMFUNC(allocate)(isc_mem_t *, size_t _ISC_MEM_FLARG);
|
||||
|
||||
|
|
|
|||
|
|
@ -349,6 +349,24 @@ mem_put(isc_mem_t *ctx, void *mem, size_t size) {
|
|||
sdallocx(mem, size, 0);
|
||||
}
|
||||
|
||||
static inline void *
|
||||
mem_realloc(isc_mem_t *ctx, void *old_ptr, size_t old_size, size_t new_size) {
|
||||
void *new_ptr = NULL;
|
||||
|
||||
new_ptr = rallocx(old_ptr, new_size, 0);
|
||||
|
||||
if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) {
|
||||
ssize_t diff_size = new_size - old_size;
|
||||
void *diff_ptr = (uint8_t *)new_ptr + old_size;
|
||||
if (diff_size > 0) {
|
||||
/* Mnemonic for "beef". */
|
||||
memset(diff_ptr, 0xbe, diff_size);
|
||||
}
|
||||
}
|
||||
|
||||
return (new_ptr);
|
||||
}
|
||||
|
||||
#define stats_bucket(ctx, size) \
|
||||
((size / STATS_BUCKET_SIZE) >= STATS_BUCKETS \
|
||||
? &ctx->stats[STATS_BUCKETS] \
|
||||
|
|
@ -872,6 +890,37 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
|
|||
return (ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
isc__mem_reget(isc_mem_t *ctx, void *old_ptr, size_t old_size,
|
||||
size_t new_size FLARG) {
|
||||
void *new_ptr = NULL;
|
||||
|
||||
if (ISC_UNLIKELY(old_ptr == NULL)) {
|
||||
REQUIRE(old_size == 0);
|
||||
new_ptr = isc__mem_get(ctx, new_size FLARG_PASS);
|
||||
} else if (ISC_UNLIKELY(new_size == 0)) {
|
||||
isc__mem_put(ctx, old_ptr, old_size FLARG_PASS);
|
||||
} else {
|
||||
DELETE_TRACE(ctx, old_ptr, old_size, file, line);
|
||||
mem_putstats(ctx, old_ptr, old_size);
|
||||
|
||||
new_ptr = mem_realloc(ctx, old_ptr, old_size, new_size);
|
||||
|
||||
mem_getstats(ctx, new_size);
|
||||
ADD_TRACE(ctx, new_ptr, new_size, file, line);
|
||||
|
||||
/*
|
||||
* We want to postpone the call to water in edge case
|
||||
* where the realloc will exactly hit on the boundary of
|
||||
* the water and we would call water twice.
|
||||
*/
|
||||
CALL_LO_WATER(ctx);
|
||||
CALL_HI_WATER(ctx);
|
||||
}
|
||||
|
||||
return (new_ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
isc__mem_reallocate(isc_mem_t *ctx, void *old_ptr, size_t new_size FLARG) {
|
||||
void *new_ptr = NULL;
|
||||
|
|
@ -888,16 +937,7 @@ isc__mem_reallocate(isc_mem_t *ctx, void *old_ptr, size_t new_size FLARG) {
|
|||
DELETE_TRACE(ctx, old_ptr, old_size, file, line);
|
||||
mem_putstats(ctx, old_ptr, old_size);
|
||||
|
||||
new_ptr = rallocx(old_ptr, new_size, 0);
|
||||
|
||||
if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) {
|
||||
ssize_t diff_size = new_size - old_size;
|
||||
void *diff_ptr = (uint8_t *)new_ptr + old_size;
|
||||
if (diff_size >= 0) {
|
||||
/* Mnemonic for "beef". */
|
||||
memset(diff_ptr, 0xbe, diff_size);
|
||||
}
|
||||
}
|
||||
new_ptr = mem_realloc(ctx, old_ptr, old_size, new_size);
|
||||
|
||||
/* Recalculate the real allocated size */
|
||||
new_size = sallocx(new_ptr, 0);
|
||||
|
|
|
|||
|
|
@ -220,6 +220,40 @@ isc_mem_inuse_test(void **state) {
|
|||
isc_mem_destroy(&mctx2);
|
||||
}
|
||||
|
||||
#define REGET_INIT_SIZE 1024
|
||||
#define REGET_GROW_SIZE 2048
|
||||
#define REGET_SHRINK_SIZE 512
|
||||
|
||||
static void
|
||||
isc_mem_reget_test(void **state) {
|
||||
uint8_t *data = isc_mem_get(test_mctx, REGET_INIT_SIZE);
|
||||
|
||||
UNUSED(state);
|
||||
|
||||
for (size_t i = 0; i < REGET_INIT_SIZE; i++) {
|
||||
data[i] = i % UINT8_MAX;
|
||||
}
|
||||
|
||||
data = isc_mem_reget(test_mctx, data, REGET_INIT_SIZE, REGET_GROW_SIZE);
|
||||
|
||||
for (size_t i = 0; i < REGET_INIT_SIZE; i++) {
|
||||
assert_int_equal(data[i], i % UINT8_MAX);
|
||||
}
|
||||
|
||||
for (size_t i = REGET_GROW_SIZE; i > 0; i--) {
|
||||
data[i - 1] = i % UINT8_MAX;
|
||||
}
|
||||
|
||||
data = isc_mem_reget(test_mctx, data, REGET_GROW_SIZE,
|
||||
REGET_SHRINK_SIZE);
|
||||
|
||||
for (size_t i = REGET_SHRINK_SIZE; i > 0; i--) {
|
||||
assert_int_equal(data[i - 1], i % UINT8_MAX);
|
||||
}
|
||||
|
||||
isc_mem_put(test_mctx, data, REGET_SHRINK_SIZE);
|
||||
}
|
||||
|
||||
#if ISC_MEM_TRACKLINES
|
||||
|
||||
/* test mem with no flags */
|
||||
|
|
@ -436,6 +470,8 @@ main(void) {
|
|||
_teardown),
|
||||
cmocka_unit_test_setup_teardown(isc_mem_inuse_test, _setup,
|
||||
_teardown),
|
||||
cmocka_unit_test_setup_teardown(isc_mem_reget_test, _setup,
|
||||
_teardown),
|
||||
|
||||
#if !defined(__SANITIZE_THREAD__)
|
||||
cmocka_unit_test_setup_teardown(isc_mem_benchmark, _setup,
|
||||
|
|
|
|||
Loading…
Reference in a new issue