summaryrefslogtreecommitdiff
path: root/lib/isc/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/isc/mem.c')
-rw-r--r--lib/isc/mem.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/lib/isc/mem.c b/lib/isc/mem.c
index 5e867f0d..4e20f8f2 100644
--- a/lib/isc/mem.c
+++ b/lib/isc/mem.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: mem.c,v 1.153.104.3 2010/05/12 00:49:31 marka Exp $ */
+/* $Id: mem.c,v 1.153.104.6 2010/08/11 23:46:20 tbox Exp $ */
/*! \file */
@@ -144,6 +144,7 @@ struct isc__mem {
size_t hi_water;
size_t lo_water;
isc_boolean_t hi_called;
+ isc_boolean_t is_overmem;
isc_mem_water_t water;
void * water_arg;
ISC_LIST(isc__mempool_t) pools;
@@ -269,6 +270,8 @@ ISC_MEMFUNC_SCOPE size_t
isc__mem_getquota(isc_mem_t *ctx);
ISC_MEMFUNC_SCOPE size_t
isc__mem_inuse(isc_mem_t *ctx);
+ISC_MEMFUNC_SCOPE isc_boolean_t
+isc__mem_isovermem(isc_mem_t *ctx);
ISC_MEMFUNC_SCOPE void
isc__mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
size_t hiwater, size_t lowater);
@@ -345,6 +348,7 @@ static struct isc__memmethods {
isc__mem_setwater,
isc__mem_waterack,
isc__mem_inuse,
+ isc__mem_isovermem,
isc__mempool_create
}
#ifndef BIND9
@@ -939,6 +943,7 @@ isc__mem_createx2(size_t init_max_size, size_t target_size,
ctx->hi_water = 0;
ctx->lo_water = 0;
ctx->hi_called = ISC_FALSE;
+ ctx->is_overmem = ISC_FALSE;
ctx->water = NULL;
ctx->water_arg = NULL;
ctx->common.impmagic = MEM_MAGIC;
@@ -1281,6 +1286,10 @@ isc___mem_get(isc_mem_t *ctx0, size_t size FLARG) {
}
ADD_TRACE(ctx, ptr, size, file, line);
+ if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
+ !ctx->is_overmem) {
+ ctx->is_overmem = ISC_TRUE;
+ }
if (ctx->hi_water != 0U && !ctx->hi_called &&
ctx->inuse > ctx->hi_water) {
call_water = ISC_TRUE;
@@ -1338,6 +1347,10 @@ isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
* when the context was pushed over hi_water but then had
* isc_mem_setwater() called with 0 for hi_water and lo_water.
*/
+ if (ctx->is_overmem &&
+ (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
+ ctx->is_overmem = ISC_FALSE;
+ }
if (ctx->hi_called &&
(ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
if (ctx->water != NULL)
@@ -1529,6 +1542,11 @@ isc___mem_allocate(isc_mem_t *ctx0, size_t size FLARG) {
#if ISC_MEM_TRACKLINES
ADD_TRACE(ctx, si, si[-1].u.size, file, line);
#endif
+ if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
+ !ctx->is_overmem) {
+ ctx->is_overmem = ISC_TRUE;
+ }
+
if (ctx->hi_water != 0U && !ctx->hi_called &&
ctx->inuse > ctx->hi_water) {
ctx->hi_called = ISC_TRUE;
@@ -1619,6 +1637,11 @@ isc___mem_free(isc_mem_t *ctx0, void *ptr FLARG) {
* when the context was pushed over hi_water but then had
* isc_mem_setwater() called with 0 for hi_water and lo_water.
*/
+ if (ctx->is_overmem &&
+ (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
+ ctx->is_overmem = ISC_FALSE;
+ }
+
if (ctx->hi_called &&
(ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
ctx->hi_called = ISC_FALSE;
@@ -1753,6 +1776,20 @@ isc__mem_setwater(isc_mem_t *ctx0, isc_mem_water_t water, void *water_arg,
(oldwater)(oldwater_arg, ISC_MEM_LOWATER);
}
+ISC_MEMFUNC_SCOPE isc_boolean_t
+isc__mem_isovermem(isc_mem_t *ctx0) {
+ isc__mem_t *ctx = (isc__mem_t *)ctx0;
+
+ REQUIRE(VALID_CONTEXT(ctx));
+
+ /*
+ * We don't bother to lock the context because 100% accuracy isn't
+ * necessary (and even if we locked the context the returned value
+ * could be different from the actual state when it's used anyway)
+ */
+ return (ctx->is_overmem);
+}
+
ISC_MEMFUNC_SCOPE void
isc__mem_setname(isc_mem_t *ctx0, const char *name, void *tag) {
isc__mem_t *ctx = (isc__mem_t *)ctx0;