* Constants.
*/
-#define ALIGNMENT 8U /*%< must be a power of 2 */
-#define ALIGNMENT_SIZE sizeof(size_info)
-#define DEBUG_TABLE_COUNT 512U
-#define STATS_BUCKETS 512U
-#define STATS_BUCKET_SIZE 32U
+#define ZERO_ALLOCATION_SIZE sizeof(void *)
+#define ALIGNMENT 8U /*%< must be a power of 2 */
+#define ALIGNMENT_SIZE sizeof(size_info)
+#define DEBUG_TABLE_COUNT 512U
+#define STATS_BUCKETS 512U
+#define STATS_BUCKET_SIZE 32U
/*
* Types.
}
#endif /* ISC_MEM_TRACKLINES */
+#define ADJUST_ZERO_ALLOCATION_SIZE(s) \
+ if (ISC_UNLIKELY(s == 0)) { \
+ s = ZERO_ALLOCATION_SIZE; \
+ }
+
/*!
* Perform a malloc, doing memory filling and overrun detection as necessary.
*/
static inline void *
mem_get(isc_mem_t *ctx, size_t size) {
- char *ret = mallocx(size, 0);
+ char *ret = NULL;
+
+ ADJUST_ZERO_ALLOCATION_SIZE(size);
+
+ ret = mallocx(size, 0);
if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) {
memset(ret, 0xbe, size); /* Mnemonic for "beef". */
/* coverity[+free : arg-1] */
static inline void
mem_put(isc_mem_t *ctx, void *mem, size_t size) {
+ ADJUST_ZERO_ALLOCATION_SIZE(size);
+
if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) {
memset(mem, 0xde, size); /* Mnemonic for "dead". */
}
mem_realloc(isc_mem_t *ctx, void *old_ptr, size_t old_size, size_t new_size) {
void *new_ptr = NULL;
+ ADJUST_ZERO_ALLOCATION_SIZE(new_size);
+
new_ptr = rallocx(old_ptr, new_size, 0);
if (ISC_UNLIKELY((ctx->flags & ISC_MEMFLAG_FILL) != 0)) {
REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp));
REQUIRE(ptr != NULL);
- REQUIRE(size > 0);
+ REQUIRE(size != 0);
ctx = *ctxp;
*ctxp = NULL;
REQUIRE(VALID_CONTEXT(ctx));
- if (ISC_LIKELY(size != 0)) {
- ptr = mem_get(ctx, size);
- }
+ ptr = mem_get(ctx, size);
mem_getstats(ctx, size);
ADD_TRACE(ctx, ptr, size, file, line);
void
isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG) {
REQUIRE(VALID_CONTEXT(ctx));
- REQUIRE(ISC_LIKELY(ptr != NULL && size != 0) ||
- ISC_UNLIKELY(ptr == NULL && size == 0));
DELETE_TRACE(ctx, ptr, size, file, line);
mem_putstats(ctx, ptr, size);
- if (ISC_LIKELY(ptr != NULL)) {
- mem_put(ctx, ptr, size);
- }
+ mem_put(ctx, ptr, size);
CALL_LO_WATER(ctx);
}
REQUIRE(VALID_CONTEXT(ctx));
- if (ISC_LIKELY(size != 0)) {
- ptr = mem_get(ctx, size);
+ ptr = mem_get(ctx, size);
- /* Recalculate the real allocated size */
- size = sallocx(ptr, 0);
- }
+ /* Recalculate the real allocated size */
+ size = sallocx(ptr, 0);
mem_getstats(ctx, size);
ADD_TRACE(ctx, ptr, size, file, line);
REQUIRE(VALID_CONTEXT(ctx));
- if (ISC_LIKELY(ptr != NULL)) {
- size = sallocx(ptr, 0);
- }
+ size = sallocx(ptr, 0);
DELETE_TRACE(ctx, ptr, size, file, line);
mem_putstats(ctx, ptr, size);
- if (ISC_LIKELY(ptr != NULL)) {
- mem_put(ctx, ptr, size);
- }
+ mem_put(ctx, ptr, size);
CALL_LO_WATER(ctx);
}
isc_mem_destroy(&mctx2);
}
+static void
+isc_mem_zeroget_test(void **state) {
+ uint8_t *data = NULL;
+ UNUSED(state);
+
+ data = isc_mem_get(test_mctx, 0);
+ assert_non_null(data);
+ isc_mem_put(test_mctx, data, 0);
+}
+
#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);
+ uint8_t *data = NULL;
UNUSED(state);
+ /* test that we can reget NULL */
+ data = isc_mem_reget(test_mctx, NULL, 0, REGET_INIT_SIZE);
+ assert_non_null(data);
+ isc_mem_put(test_mctx, data, REGET_INIT_SIZE);
+
+ /* test that we can re-get a zero-length allocation */
+ data = isc_mem_get(test_mctx, 0);
+ assert_non_null(data);
+
+ data = isc_mem_reget(test_mctx, data, 0, REGET_INIT_SIZE);
+ assert_non_null(data);
+
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);
+ assert_non_null(data);
for (size_t i = 0; i < REGET_INIT_SIZE; i++) {
assert_int_equal(data[i], i % UINT8_MAX);
data = isc_mem_reget(test_mctx, data, REGET_GROW_SIZE,
REGET_SHRINK_SIZE);
+ assert_non_null(data);
for (size_t i = REGET_SHRINK_SIZE; i > 0; i--) {
assert_int_equal(data[i - 1], i % UINT8_MAX);
_teardown),
cmocka_unit_test_setup_teardown(isc_mem_inuse_test, _setup,
_teardown),
+ cmocka_unit_test_setup_teardown(isc_mem_zeroget_test, _setup,
+ _teardown),
cmocka_unit_test_setup_teardown(isc_mem_reget_test, _setup,
_teardown),