int ret;
if (dt_mctx == NULL)
- result = isc_mem_create2(0, 0, &dt_mctx, 0);
+ result = isc_mem_create(0, 0, &dt_mctx);
if (result != ISC_R_SUCCESS)
goto unlock;
isc_mem_setname(dt_mctx, "dt", NULL);
* ISC_MEMFLAG_INTERNAL as it will free up memory still being used
* by libcrypto.
*/
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &dst__memory_pool, 0);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &dst__memory_pool, 0);
if (result != ISC_R_SUCCESS)
return (result);
isc_mem_setname(dst__memory_pool, "dst", NULL);
int ret;
if (state_mctx == NULL)
- result = isc_mem_create2(0, 0, &state_mctx, 0);
+ result = isc_mem_create(0, 0, &state_mctx);
if (result != ISC_R_SUCCESS)
goto unlock;
isc_mem_setname(state_mctx, "geoip_state", NULL);
if (!thread_key_initialized) {
LOCK(&thread_key_mutex);
if (thread_key_mctx == NULL)
- result = isc_mem_create2(0, 0, &thread_key_mctx, 0);
+ result = isc_mem_create(0, 0, &thread_key_mctx);
if (result != ISC_R_SUCCESS)
goto unlock;
isc_mem_setname(thread_key_mctx, "threadkey", NULL);
#endif
/*
- * Flags for isc_mem_create2()calls.
+ * Flags for isc_mem_createx() calls.
*/
#define ISC_MEMFLAG_NOLOCK 0x00000001 /* no lock is necessary */
#define ISC_MEMFLAG_INTERNAL 0x00000002 /* use internal malloc */
#define ISC_MEMFLAG_DEFAULT ISC_MEMFLAG_INTERNAL|ISC_MEMFLAG_FILL
#endif
-
-/*%<
- * We use either isc___mem (three underscores) or isc__mem (two) depending on
- * whether it's for BIND9's internal purpose (with -DBIND9) or generic export
- * library.
- */
-#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_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)
-#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p) _ISC_MEM_FILELINE)
-#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c) _ISC_MEM_FILELINE)
-
/*%
* isc_mem_putanddetach() is a convenience function for use where you
* have a structure with an attached memory context.
* \endcode
*/
+/*% memory and memory pool methods */
+typedef struct isc_memmethods {
+ void *(*memget)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG);
+ void (*memput)(isc_mem_t *mctx, void *ptr, size_t size _ISC_MEM_FLARG);
+ void (*memputanddetach)(isc_mem_t **mctxp, void *ptr,
+ size_t size _ISC_MEM_FLARG);
+ void *(*memallocate)(isc_mem_t *mctx, size_t size _ISC_MEM_FLARG);
+ void *(*memreallocate)(isc_mem_t *mctx, void *ptr,
+ size_t size _ISC_MEM_FLARG);
+ char *(*memstrdup)(isc_mem_t *mctx, const char *s _ISC_MEM_FLARG);
+ void (*memfree)(isc_mem_t *mctx, void *ptr _ISC_MEM_FLARG);
+} isc_memmethods_t;
+
/*%
* This structure is actually just the common prefix of a memory context
* implementation's version of an isc_mem_t.
struct isc_mem {
unsigned int impmagic;
unsigned int magic;
+ isc_memmethods_t *methods;
};
#define ISCAPI_MCTX_MAGIC ISC_MAGIC('A','m','c','x')
#define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \
(mp)->magic == ISCAPI_MPOOL_MAGIC)
+/*%
+ * These functions are actually implemented in isc__mem_<function>
+ * (two underscores). The single-underscore macros are used to pass
+ * __FILE__ and __LINE__, and in the case of the put functions, to
+ * set the pointer being freed to NULL in the calling function.
+ *
+ * Many of these functions have a further isc___mem_<function>
+ * (three underscores) implementation, which is called indirectly
+ * via the isc_memmethods structure in the mctx so that dynamically
+ * loaded modules can use them even if named is statically linked.
+ */
+
+#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_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)
+#define isc_mem_strdup(c, p) ISCMEMFUNC(strdup)((c), (p) _ISC_MEM_FILELINE)
+#define isc_mempool_get(c) ISCMEMPOOLFUNC(get)((c) _ISC_MEM_FILELINE)
+
#define isc_mem_put(c, p, s) \
do { \
ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \
isc_mem_create(size_t max_size, size_t target_size,
isc_mem_t **mctxp);
-isc_result_t
-isc_mem_create2(size_t max_size, size_t target_size,
- isc_mem_t **mctxp, unsigned int flags);
-
isc_result_t
isc_mem_createx(size_t max_size, size_t target_size,
isc_memalloc_t memalloc, isc_memfree_t memfree,
- void *arg, isc_mem_t **mctxp);
-
-isc_result_t
-isc_mem_createx2(size_t max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree,
- void *arg, isc_mem_t **mctxp, unsigned int flags);
+ void *arg, isc_mem_t **mctxp, unsigned int flags);
/*!<
* \brief Create a memory context.
void
ISCMEMPOOLFUNC(put)(isc_mempool_t *, void * _ISC_MEM_FLARG);
-void
-isc__mem_printactive(isc_mem_t *mctx, FILE *file);
-/*%<
- * For internal use by the isc module and its unit tests, these functions
- * print lists of active memory blocks for a single memory context or for
- * all contexts.
- */
-
ISC_LANG_ENDDECLS
#endif /* ISC_MEM_H */
#include <isc/util.h>
#include <isc/xml.h>
+#include "mem_p.h"
+
#define MCTXLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) LOCK(l)
#define MCTXUNLOCK(m, l) if (((m)->flags & ISC_MEMFLAG_NOLOCK) == 0) UNLOCK(l)
static void
print_active(isc__mem_t *ctx, FILE *out);
+#endif /* ISC_MEM_TRACKLINES */
+
+static void *
+isc___mem_get(isc_mem_t *ctx, size_t size FLARG);
+static void
+isc___mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG);
+static void
+isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG);
+static void *
+isc___mem_allocate(isc_mem_t *ctx, size_t size FLARG);
+static void *
+isc___mem_reallocate(isc_mem_t *ctx, void *ptr, size_t size FLARG);
+static char *
+isc___mem_strdup(isc_mem_t *mctx, const char *s FLARG);
+static void
+isc___mem_free(isc_mem_t *ctx, void *ptr FLARG);
+
+static isc_memmethods_t memmethods = {
+ isc___mem_get,
+ isc___mem_put,
+ isc___mem_putanddetach,
+ isc___mem_allocate,
+ isc___mem_reallocate,
+ isc___mem_strdup,
+ isc___mem_free,
+};
+
+#if ISC_MEM_TRACKLINES
/*!
* mctx must be locked.
*/
isc_result_t
isc_mem_createx(size_t init_max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
- isc_mem_t **ctxp)
-{
- return (isc_mem_createx2(init_max_size, target_size, memalloc, memfree,
- arg, ctxp, isc_mem_defaultflags));
-
-}
-
-isc_result_t
-isc_mem_createx2(size_t init_max_size, size_t target_size,
- isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
- isc_mem_t **ctxp, unsigned int flags)
+ isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
+ isc_mem_t **ctxp, unsigned int flags)
{
isc__mem_t *ctx;
isc_result_t result;
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
ctx = (memalloc)(arg, sizeof(*ctx));
- if (ctx == NULL)
+ if (ctx == NULL) {
return (ISC_R_NOMEMORY);
+ }
if ((flags & ISC_MEMFLAG_NOLOCK) == 0) {
result = isc_mutex_init(&ctx->lock);
ctx->water_arg = NULL;
ctx->common.impmagic = MEM_MAGIC;
ctx->common.magic = ISCAPI_MCTX_MAGIC;
+ ctx->common.methods = (isc_memmethods_t *)&memmethods;
ctx->memalloc = memalloc;
ctx->memfree = memfree;
ctx->arg = arg;
UNLOCK(&contextslock);
*ctxp = (isc_mem_t *)ctx;
+
return (ISC_R_SUCCESS);
error:
*/
void
-isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
+isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
REQUIRE(ctxp != NULL && VALID_CONTEXT(*ctxp));
REQUIRE(ptr != NULL);
isc__mem_t *ctx = (isc__mem_t *)*ctxp;
}
void *
-isc__mem_get(isc_mem_t *ctx0, size_t size FLARG) {
+isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
isc__mem_t *ctx = (isc__mem_t *)ctx0;
void *ptr;
bool call_water = false;
}
void
-isc__mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
+isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
isc__mem_t *ctx = (isc__mem_t *)ctx0;
bool call_water = false;
size_info *si;
}
void *
-isc__mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
+isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_info *si;
bool call_water = false;
}
void *
-isc__mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
+isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
isc__mem_t *ctx = (isc__mem_t *)ctx0;
void *new_ptr = NULL;
size_t oldsize, copysize;
}
void
-isc__mem_free(isc_mem_t *ctx0, void *ptr FLARG) {
+isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) {
isc__mem_t *ctx = (isc__mem_t *)ctx0;
size_info *si;
size_t size;
*/
char *
-isc__mem_strdup(isc_mem_t *mctx0, const char *s FLARG) {
+isc___mem_strdup(isc_mem_t *mctx0, const char *s FLARG) {
isc__mem_t *mctx = (isc__mem_t *)mctx0;
size_t len;
char *ns;
void
isc_mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg,
- size_t hiwater, size_t lowater)
+ size_t hiwater, size_t lowater)
{
isc__mem_t *ctx = (isc__mem_t *)ctx0;
bool callwater = false;
#if ISC_MEMPOOL_NAMES
if (mpctx->allocated > 0)
UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc__mempool_destroy(): mempool %s "
+ "isc_mempool_destroy(): mempool %s "
"leaked memory",
mpctx->name);
#endif
return (fillcount);
}
-void
-isc_mem_printactive(isc_mem_t *ctx0, FILE *file) {
-#if ISC_MEM_TRACKLINES
- isc__mem_t *ctx = (isc__mem_t *)ctx0;
-
- REQUIRE(VALID_CONTEXT(ctx));
- REQUIRE(file != NULL);
-
- print_active(ctx, file);
-#else
- UNUSED(ctx0);
- UNUSED(file);
-#endif
-}
-
-
/*
* Requires contextslock to be held by caller.
*/
isc_result_t
isc_mem_create(size_t init_max_size, size_t target_size, isc_mem_t **mctxp) {
- return (isc_mem_createx2(init_max_size, target_size,
- default_memalloc, default_memfree,
- NULL, mctxp, isc_mem_defaultflags));
+ return (isc_mem_createx(init_max_size, target_size,
+ default_memalloc, default_memfree,
+ NULL, mctxp, isc_mem_defaultflags));
}
-isc_result_t
-isc_mem_create2(size_t init_max_size, size_t target_size, isc_mem_t **mctxp,
- unsigned int flags)
-{
- return (isc_mem_createx2(init_max_size, target_size,
- default_memalloc, default_memfree,
- NULL, mctxp, flags));
+void *
+isc__mem_get(isc_mem_t *mctx, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memget(mctx, size FLARG_PASS));
+
+}
+
+void
+isc__mem_put(isc_mem_t *mctx, void *ptr, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ mctx->methods->memput(mctx, ptr, size FLARG_PASS);
+}
+
+void
+isc__mem_putanddetach(isc_mem_t **mctxp, void *ptr, size_t size FLARG) {
+ REQUIRE(mctxp != NULL && ISCAPI_MCTX_VALID(*mctxp));
+
+ (*mctxp)->methods->memputanddetach(mctxp, ptr, size FLARG_PASS);
+}
+
+void *
+isc__mem_allocate(isc_mem_t *mctx, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memallocate(mctx, size FLARG_PASS));
+}
+
+void *
+isc__mem_reallocate(isc_mem_t *mctx, void *ptr, size_t size FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memreallocate(mctx, ptr, size FLARG_PASS));
+}
+
+char *
+isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ return (mctx->methods->memstrdup(mctx, s FLARG_PASS));
+}
+
+void
+isc__mem_free(isc_mem_t *mctx, void *ptr FLARG) {
+ REQUIRE(ISCAPI_MCTX_VALID(mctx));
+
+ mctx->methods->memfree(mctx, ptr FLARG_PASS);
+}
+
+void
+isc__mem_printactive(isc_mem_t *ctx0, FILE *file) {
+#if ISC_MEM_TRACKLINES
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
+ REQUIRE(VALID_CONTEXT(ctx));
+ REQUIRE(file != NULL);
+
+ print_active(ctx, file);
+#else
+ UNUSED(ctx0);
+ UNUSED(file);
+#endif
}
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#ifndef ISC_MEM_P_H
+#define ISC_MEM_P_H
+
+/*! \file */
+
+void
+isc__mem_printactive(isc_mem_t *mctx, FILE *file);
+/*%<
+ * For use by unit tests, prints active memory blocks for
+ * a single memory context.
+ */
+
+#endif /* ISC_MEM_P_H */
isc_mem_t *mctx = NULL;
uintptr_t i;
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &mctx, 0);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_ht_init(&ht, mctx, bits);
unsigned char *tkey;
size_t tksize;
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &mctx, 0);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_ht_init(&ht, mctx, 16);
#include <atf-c.h>
-#include "isctest.h"
-
#include <isc/file.h>
#include <isc/mem.h>
#include <isc/print.h>
#include <isc/result.h>
#include <isc/stdio.h>
+#include "../mem_p.h"
+
+#include "isctest.h"
+
static void *
default_memalloc(void *arg, size_t size) {
UNUSED(arg);
isc_mem_destroy(&localmctx);
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &localmctx,
- ISC_MEMFLAG_FILL | ISC_MEMFLAG_INTERNAL);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &localmctx,
+ ISC_MEMFLAG_FILL | ISC_MEMFLAG_INTERNAL);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = isc_mempool_create(localmctx, 2, &mp1);
/* Local alloc, free */
mctx2 = NULL;
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &mctx2, 0);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx2, 0);
if (result != ISC_R_SUCCESS)
goto out;
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
mctx2 = NULL;
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &mctx2, 0);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx2, 0);
if (result != ISC_R_SUCCESS)
goto out;
result = isc_test_begin(NULL, true, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &mctx2, 0);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx2, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
isc_mem_debugging = 0;
ptr = isc_mem_get(mctx2, 2048);
ATF_CHECK(ptr != NULL);
- isc_mem_printactive(mctx2, f);
+ isc__mem_printactive(mctx2, f);
isc_mem_put(mctx2, ptr, 2048);
isc_mem_destroy(&mctx2);
isc_stdio_close(f);
result = isc_test_begin(NULL, false, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &mctx2, 0);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx2, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
ptr = isc_mem_get(mctx2, 2048);
ATF_CHECK(ptr != NULL);
- isc_mem_printactive(mctx2, f);
+ isc__mem_printactive(mctx2, f);
isc_mem_put(mctx2, ptr, 2048);
isc_mem_destroy(&mctx2);
isc_stdio_close(f);
result = isc_test_begin(NULL, true, 0);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = isc_mem_createx2(0, 0, default_memalloc, default_memfree,
- NULL, &mctx2, 0);
+ result = isc_mem_createx(0, 0, default_memalloc, default_memfree,
+ NULL, &mctx2, 0);
isc_mem_debugging = ISC_MEM_DEBUGTRACE;
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
ptr = isc_mem_get(mctx2, 2048);
ATF_CHECK(ptr != NULL);
- isc_mem_printactive(mctx2, f);
+ isc__mem_printactive(mctx2, f);
isc_mem_put(mctx2, ptr, 2048);
isc_mem_destroy(&mctx2);
isc_stdio_close(f);
./lib/isc/log.c C 1999,2000,2001,2002,2003,2004,2005,2006,2007,2009,2011,2012,2013,2014,2016,2017,2018
./lib/isc/md5.c C 2000,2001,2004,2005,2007,2009,2014,2015,2016,2017,2018
./lib/isc/mem.c C 1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2012,2013,2014,2015,2016,2017,2018
+./lib/isc/mem_p.h C 2018
./lib/isc/mutexblock.c C 1999,2000,2001,2004,2005,2007,2011,2012,2016,2018
./lib/isc/netaddr.c C 1999,2000,2001,2002,2004,2005,2007,2010,2011,2012,2014,2015,2016,2017,2018
./lib/isc/netscope.c C 2002,2004,2005,2006,2007,2016,2018