mem.c 24 KB
Newer Older
Bob Halley's avatar
base  
Bob Halley committed
1
/*
Bob Halley's avatar
Bob Halley committed
2
 * Copyright (C) 1997, 1998, 1999  Internet Software Consortium.
Bob Halley's avatar
Bob Halley committed
3
 * 
Bob Halley's avatar
base  
Bob Halley committed
4 5 6
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
Bob Halley's avatar
Bob Halley committed
7
 * 
Bob Halley's avatar
base  
Bob Halley committed
8 9 10 11 12 13 14 15 16 17
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

Bob Halley's avatar
Bob Halley committed
18
#include <config.h>
Bob Halley's avatar
base  
Bob Halley committed
19 20 21

#include <stdio.h>
#include <stdlib.h>
Bob Halley's avatar
Bob Halley committed
22
#include <stddef.h>
Bob Halley's avatar
base  
Bob Halley committed
23 24
#include <string.h>

Michael Graff's avatar
Michael Graff committed
25 26
#include <limits.h>

Bob Halley's avatar
base  
Bob Halley committed
27
#include <isc/assertions.h>
28
#include <isc/error.h>
Bob Halley's avatar
Bob Halley committed
29
#include <isc/mem.h>
Bob Halley's avatar
Bob Halley committed
30

31
#ifndef ISC_SINGLETHREADED
Bob Halley's avatar
update  
Bob Halley committed
32
#include <isc/mutex.h>
Bob Halley's avatar
Bob Halley committed
33 34
#include "util.h"
#else
Bob Halley's avatar
Bob Halley committed
35 36
#define LOCK(l)
#define UNLOCK(l)
Bob Halley's avatar
update  
Bob Halley committed
37 38
#endif

Bob Halley's avatar
Bob Halley committed
39
#ifndef ISC_MEM_FILL
40 41
	/*
	 * XXXMPA
Bob Halley's avatar
Bob Halley committed
42
	 * We want this on during development to catch:
43 44 45 46 47 48
	 * 1. some reference after free bugs.
	 * 2. some failure to initalise bugs.
	 */
#define ISC_MEM_FILL 1
#endif

Bob Halley's avatar
base  
Bob Halley committed
49 50 51 52
/*
 * Types.
 */

Bob Halley's avatar
Bob Halley committed
53
typedef struct {
Bob Halley's avatar
base  
Bob Halley committed
54
	void *			next;
Bob Halley's avatar
Bob Halley committed
55
} element;
Bob Halley's avatar
base  
Bob Halley committed
56 57 58 59 60 61

typedef struct {
	size_t			size;
	/*
	 * This structure must be ALIGNMENT_SIZE bytes.
	 */
Bob Halley's avatar
Bob Halley committed
62
} size_info;
Bob Halley's avatar
base  
Bob Halley committed
63 64

struct stats {
Bob Halley's avatar
Bob Halley committed
65 66 67 68
	unsigned long		gets;
	unsigned long		totalgets;
	unsigned long		blocks;
	unsigned long		freefrags;
Bob Halley's avatar
base  
Bob Halley committed
69 70
};

71 72
#define MEM_MAGIC		0x4D656d43U	/* MemC. */
#define VALID_CONTEXT(c)	((c) != NULL && (c)->magic == MEM_MAGIC)
Bob Halley's avatar
Bob Halley committed
73

74
struct isc_mem {
Bob Halley's avatar
Bob Halley committed
75 76
	unsigned int		magic;
	isc_mutex_t		lock;
77 78 79
	isc_memalloc_t		memalloc;
	isc_memfree_t		memfree;
	void *			arg;
Bob Halley's avatar
base  
Bob Halley committed
80 81
	size_t			max_size;
	size_t			mem_target;
Bob Halley's avatar
Bob Halley committed
82 83
	element **		freelists;
	element *		basic_blocks;
84 85 86
	unsigned char **	basic_table;
	unsigned int		basic_table_count;
	unsigned int		basic_table_size;
Bob Halley's avatar
Bob Halley committed
87 88
	unsigned char *		lowest;
	unsigned char *		highest;
89
	isc_boolean_t		checkfree;
Bob Halley's avatar
base  
Bob Halley committed
90
	struct stats *		stats;
91
	size_t			quota;
Bob Halley's avatar
Bob Halley committed
92
	size_t			total;
Michael Graff's avatar
Michael Graff committed
93 94 95 96 97 98 99
	ISC_LIST(isc_mempool_t)	pools;
};

#define MEMPOOL_MAGIC		0x4D454d70U	/* MEMp. */
#define VALID_MEMPOOL(c)	((c) != NULL && (c)->magic == MEMPOOL_MAGIC)

struct isc_mempool {
Michael Graff's avatar
Michael Graff committed
100
	/* always unlocked */
Michael Graff's avatar
Michael Graff committed
101
	unsigned int	magic;		/* magic number */
Michael Graff's avatar
Michael Graff committed
102
	isc_mutex_t    *lock;		/* optional lock */
Michael Graff's avatar
Michael Graff committed
103
	isc_mem_t      *mctx;		/* our memory context */
Michael Graff's avatar
Michael Graff committed
104 105 106
	/* locked via the memory context's lock */
	ISC_LINK(isc_mempool_t)	link;	/* next pool in this mem context */
	/* optionally locked from here down */
Michael Graff's avatar
Michael Graff committed
107 108 109 110 111 112 113 114 115
	element	       *items;		/* low water item list */
	size_t		size;		/* size of each item on this pool */
	unsigned int	maxalloc;	/* max number of items allowed */
	unsigned int	allocated;	/* # of items currently given out */
	unsigned int	freecount;	/* # of items on reserved list */
	unsigned int	freemax;	/* # of items allowed on free list */
	unsigned int	fillcount;	/* # of items to fetch on each fill */
	/* Stats only. */
	unsigned int	gets;		/* # of requests to this pool */
Bob Halley's avatar
base  
Bob Halley committed
116 117 118 119
};

/* Forward. */

Michael Graff's avatar
Michael Graff committed
120
static inline size_t		quantize(size_t);
Bob Halley's avatar
Bob Halley committed
121 122
static inline void		mem_putunlocked(isc_mem_t *, void *, size_t);
static inline void *		mem_getunlocked(isc_mem_t *, size_t);
Bob Halley's avatar
base  
Bob Halley committed
123

Bob Halley's avatar
Bob Halley committed
124
/* Constants. */
Bob Halley's avatar
base  
Bob Halley committed
125 126 127 128 129

#define DEF_MAX_SIZE		1100
#define DEF_MEM_TARGET		4096
#define ALIGNMENT_SIZE		sizeof (void *)
#define NUM_BASIC_BLOCKS	64			/* must be > 1 */
130
#define TABLE_INCREMENT		1024
Bob Halley's avatar
base  
Bob Halley committed
131 132 133

/* Private Inline-able. */

134
static inline size_t
Bob Halley's avatar
base  
Bob Halley committed
135
quantize(size_t size) {
136
	int temp;
Bob Halley's avatar
base  
Bob Halley committed
137 138

	/*
139
	 * Round up the result in order to get a size big
Bob Halley's avatar
base  
Bob Halley committed
140 141 142
	 * enough to satisfy the request and be aligned on ALIGNMENT_SIZE
	 * byte boundaries.
	 */
143 144 145

	temp = size + (ALIGNMENT_SIZE - 1);
	return (temp - temp % ALIGNMENT_SIZE); 
Bob Halley's avatar
base  
Bob Halley committed
146 147
}

148 149 150 151 152 153 154 155 156 157 158
/* Private. */

static void *
default_memalloc(void *arg, size_t size) {
	(void)arg;
	return (malloc(size));
}

static void
default_memfree(void *arg, void *ptr) {
	(void)arg;
James Brister's avatar
James Brister committed
159
	free(ptr);
160 161
}

Bob Halley's avatar
base  
Bob Halley committed
162 163
/* Public. */

Bob Halley's avatar
Bob Halley committed
164
isc_result_t
165 166 167
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)
Bob Halley's avatar
Bob Halley committed
168
{
169
	isc_mem_t *ctx;
Bob Halley's avatar
Bob Halley committed
170 171

	REQUIRE(ctxp != NULL && *ctxp == NULL);
172 173
	REQUIRE(memalloc != NULL);
	REQUIRE(memfree != NULL);
Bob Halley's avatar
base  
Bob Halley committed
174

175
	ctx = (memalloc)(arg, sizeof *ctx);
Michael Graff's avatar
Michael Graff committed
176 177 178
	if (ctx == NULL)
		return (ISC_R_NOMEMORY);

Bob Halley's avatar
base  
Bob Halley committed
179 180 181 182 183 184 185 186
	if (init_max_size == 0)
		ctx->max_size = DEF_MAX_SIZE;
	else
		ctx->max_size = init_max_size;
	if (target_size == 0)
		ctx->mem_target = DEF_MEM_TARGET;
	else
		ctx->mem_target = target_size;
187 188 189 190
	ctx->memalloc = memalloc;
	ctx->memfree = memfree;
	ctx->arg = arg;
	ctx->freelists = (memalloc)(arg, ctx->max_size * sizeof (element *));
Bob Halley's avatar
base  
Bob Halley committed
191
	if (ctx->freelists == NULL) {
192
		(memfree)(arg, ctx);
Bob Halley's avatar
Bob Halley committed
193
		return (ISC_R_NOMEMORY);
Bob Halley's avatar
base  
Bob Halley committed
194
	}
195
	ctx->checkfree = ISC_TRUE;
Bob Halley's avatar
Bob Halley committed
196 197
	memset(ctx->freelists, 0,
	       ctx->max_size * sizeof (element *));
198 199
	ctx->stats = (memalloc)(arg,
				(ctx->max_size+1) * sizeof (struct stats));
Bob Halley's avatar
base  
Bob Halley committed
200
	if (ctx->stats == NULL) {
201 202
		(memfree)(arg, ctx->freelists);
		(memfree)(arg, ctx);
Bob Halley's avatar
Bob Halley committed
203
		return (ISC_R_NOMEMORY);
Bob Halley's avatar
base  
Bob Halley committed
204 205 206
	}
	memset(ctx->stats, 0, (ctx->max_size + 1) * sizeof (struct stats));
	ctx->basic_blocks = NULL;
207 208 209
	ctx->basic_table = NULL;
	ctx->basic_table_count = 0;
	ctx->basic_table_size = 0;
Bob Halley's avatar
base  
Bob Halley committed
210 211
	ctx->lowest = NULL;
	ctx->highest = NULL;
Bob Halley's avatar
Bob Halley committed
212
	if (isc_mutex_init(&ctx->lock) != ISC_R_SUCCESS) {
213 214 215
		(memfree)(arg, ctx->stats);
		(memfree)(arg, ctx->freelists);
		(memfree)(arg, ctx);
Bob Halley's avatar
Bob Halley committed
216
		UNEXPECTED_ERROR(__FILE__, __LINE__,
Bob Halley's avatar
Bob Halley committed
217
				 "isc_mutex_init() failed");
Bob Halley's avatar
Bob Halley committed
218
		return (ISC_R_UNEXPECTED);
Bob Halley's avatar
update  
Bob Halley committed
219
	}
220
	ctx->quota = 0;
Bob Halley's avatar
Bob Halley committed
221
	ctx->total = 0;
Bob Halley's avatar
Bob Halley committed
222
	ctx->magic = MEM_MAGIC;
Michael Graff's avatar
Michael Graff committed
223 224
	ISC_LIST_INIT(ctx->pools);

Bob Halley's avatar
base  
Bob Halley committed
225
	*ctxp = ctx;
Bob Halley's avatar
Bob Halley committed
226
	return (ISC_R_SUCCESS);
Bob Halley's avatar
base  
Bob Halley committed
227 228
}

229 230 231 232 233 234 235 236 237
isc_result_t
isc_mem_create(size_t init_max_size, size_t target_size,
	       isc_mem_t **ctxp)
{
	return (isc_mem_createx(init_max_size, target_size,
				default_memalloc, default_memfree, NULL,
				ctxp));
}

Bob Halley's avatar
base  
Bob Halley committed
238
void
239
isc_mem_destroy(isc_mem_t **ctxp) {
240
	unsigned int i;
241
	isc_mem_t *ctx;
242

Bob Halley's avatar
base  
Bob Halley committed
243
	REQUIRE(ctxp != NULL);
244
	ctx = *ctxp;
Bob Halley's avatar
Bob Halley committed
245 246 247
	REQUIRE(VALID_CONTEXT(ctx));

	ctx->magic = 0;
248

Michael Graff's avatar
Michael Graff committed
249 250
	INSIST(ISC_LIST_EMPTY(ctx->pools));

251 252 253 254 255 256 257 258 259 260 261
	if (ctx->checkfree) {
		for (i = 0; i <= ctx->max_size; i++)
			INSIST(ctx->stats[i].gets == 0);
	}

#if 0					/* XXX brister debugging */
	for (i = 0; i < ctx->basic_table_count; i++)
		memset(ctx->basic_table[i], 0x0,
		       NUM_BASIC_BLOCKS * ctx->mem_target);
#endif
	
262 263

	for (i = 0; i < ctx->basic_table_count; i++)
264 265 266 267
		(ctx->memfree)(ctx->arg, ctx->basic_table[i]);
	(ctx->memfree)(ctx->arg, ctx->freelists);
	(ctx->memfree)(ctx->arg, ctx->stats);
	(ctx->memfree)(ctx->arg, ctx->basic_table);
268

Bob Halley's avatar
Bob Halley committed
269
	(void)isc_mutex_destroy(&ctx->lock);
270
	(ctx->memfree)(ctx->arg, ctx);
Bob Halley's avatar
base  
Bob Halley committed
271 272 273 274

	*ctxp = NULL;
}

275 276 277 278 279 280 281 282 283 284 285
isc_result_t
isc_mem_restore(isc_mem_t *ctx) {
	isc_result_t result;

	result = isc_mutex_init(&ctx->lock); 
	if (result != ISC_R_SUCCESS)
		ctx->magic = 0;

	return (result);
}

286
static void
287
more_basic_blocks(isc_mem_t *ctx) {
288 289 290 291 292
	void *new;
	unsigned char *curr, *next;
	unsigned char *first, *last;
	unsigned char **table;
	unsigned int table_size;
Bob Halley's avatar
Bob Halley committed
293
	size_t increment;
294 295 296 297
	int i;

	/* Require: we hold the context lock. */

298 299 300
	/*
	 * Did we hit the quota for this context?
	 */
Bob Halley's avatar
Bob Halley committed
301 302 303
	increment = NUM_BASIC_BLOCKS * ctx->mem_target;
	if (ctx->quota != 0 && ctx->total + increment > ctx->quota)
		return;
304 305 306

	INSIST(ctx->basic_table_count <= ctx->basic_table_size);
	if (ctx->basic_table_count == ctx->basic_table_size) {
307
		table_size = ctx->basic_table_size + TABLE_INCREMENT;
308 309
		table = (ctx->memalloc)(ctx->arg,
					table_size * sizeof (unsigned char *));
310 311
		if (table == NULL)
			return;
312 313 314 315
		if (ctx->basic_table_size != 0) {
			memcpy(table, ctx->basic_table,
			       ctx->basic_table_size *
			       sizeof (unsigned char *));
316
			(ctx->memfree)(ctx->arg, ctx->basic_table);
317
		}
318 319
		ctx->basic_table = table;
		ctx->basic_table_size = table_size;
320
	}
321

322
	new = (ctx->memalloc)(ctx->arg, NUM_BASIC_BLOCKS * ctx->mem_target);
323
	if (new == NULL)
324
		return;
Bob Halley's avatar
Bob Halley committed
325
	ctx->total += increment;
326 327
	ctx->basic_table[ctx->basic_table_count] = new;
	ctx->basic_table_count++;
328

329 330 331
	curr = new;
	next = curr + ctx->mem_target;
	for (i = 0; i < (NUM_BASIC_BLOCKS - 1); i++) {
Bob Halley's avatar
Bob Halley committed
332
		((element *)curr)->next = next;
333 334 335 336 337 338 339
		curr = next;
		next += ctx->mem_target;
	}
	/*
	 * curr is now pointing at the last block in the
	 * array.
	 */
Bob Halley's avatar
Bob Halley committed
340
	((element *)curr)->next = NULL;
341 342 343 344 345 346 347 348 349
	first = new;
	last = first + NUM_BASIC_BLOCKS * ctx->mem_target - 1;
	if (first < ctx->lowest || ctx->lowest == NULL)
		ctx->lowest = first;
	if (last > ctx->highest)
		ctx->highest = last;
	ctx->basic_blocks = new;
}

Bob Halley's avatar
base  
Bob Halley committed
350
void *
Bob Halley's avatar
Bob Halley committed
351
__isc_mem_get(isc_mem_t *ctx, size_t size)
Michael Graff's avatar
Michael Graff committed
352
{
Bob Halley's avatar
base  
Bob Halley committed
353 354 355
	void *ret;

	REQUIRE(size > 0);
Bob Halley's avatar
Bob Halley committed
356
	REQUIRE(VALID_CONTEXT(ctx));
Michael Graff's avatar
Michael Graff committed
357

Bob Halley's avatar
Bob Halley committed
358
	LOCK(&ctx->lock);
Bob Halley's avatar
Bob Halley committed
359
	ret = mem_getunlocked(ctx, size);
Michael Graff's avatar
Michael Graff committed
360 361 362 363 364 365
	UNLOCK(&ctx->lock);

	return (ret);
}

static inline void *
Bob Halley's avatar
Bob Halley committed
366
mem_getunlocked(isc_mem_t *ctx, size_t size)
Michael Graff's avatar
Michael Graff committed
367 368 369
{
	size_t new_size = quantize(size);
	void *ret;
Bob Halley's avatar
base  
Bob Halley committed
370 371 372

	if (size >= ctx->max_size || new_size >= ctx->max_size) {
		/* memget() was called on something beyond our upper limit. */
Bob Halley's avatar
Bob Halley committed
373 374 375 376
		if (ctx->quota != 0 && ctx->total + size > ctx->quota) {
			ret = NULL;
			goto done;
		}
377
		ret = (ctx->memalloc)(ctx->arg, size);
Bob Halley's avatar
base  
Bob Halley committed
378
		if (ret != NULL) {
Bob Halley's avatar
Bob Halley committed
379
			ctx->total += size;
Bob Halley's avatar
base  
Bob Halley committed
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
			ctx->stats[ctx->max_size].gets++;
			ctx->stats[ctx->max_size].totalgets++;
		}
		goto done;
	}

	/* 
	 * If there are no blocks in the free list for this size, get a chunk
	 * of memory and then break it up into "new_size"-sized blocks, adding
	 * them to the free list.
	 */
	if (ctx->freelists[new_size] == NULL) {
		int i, frags;
		size_t total_size;
		void *new;
Bob Halley's avatar
Bob Halley committed
395
		unsigned char *curr, *next;
Bob Halley's avatar
base  
Bob Halley committed
396 397

		if (ctx->basic_blocks == NULL) {
398 399
			more_basic_blocks(ctx);
			if (ctx->basic_blocks == NULL) {
Bob Halley's avatar
base  
Bob Halley committed
400 401 402 403 404 405 406 407 408 409 410 411 412 413
				ret = NULL;
				goto done;
			}
		}
		total_size = ctx->mem_target;
		new = ctx->basic_blocks;
		ctx->basic_blocks = ctx->basic_blocks->next;
		frags = total_size / new_size;
		ctx->stats[new_size].blocks++;
		ctx->stats[new_size].freefrags += frags;
		/* Set up a linked-list of blocks of size "new_size". */
		curr = new;
		next = curr + new_size;
		for (i = 0; i < (frags - 1); i++) {
Bob Halley's avatar
Bob Halley committed
414
			((element *)curr)->next = next;
Bob Halley's avatar
base  
Bob Halley committed
415 416 417 418
			curr = next;
			next += new_size;
		}
		/* curr is now pointing at the last block in the array. */
Bob Halley's avatar
Bob Halley committed
419
		((element *)curr)->next = NULL;
Bob Halley's avatar
base  
Bob Halley committed
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
		ctx->freelists[new_size] = new;
	}

	/* The free list uses the "rounded-up" size "new_size": */
	ret = ctx->freelists[new_size];
	ctx->freelists[new_size] = ctx->freelists[new_size]->next;

	/* 
	 * The stats[] uses the _actual_ "size" requested by the
	 * caller, with the caveat (in the code above) that "size" >= the
	 * max. size (max_size) ends up getting recorded as a call to
	 * max_size.
	 */
	ctx->stats[size].gets++;
	ctx->stats[size].totalgets++;
	ctx->stats[new_size].freefrags--;

 done:

439 440 441 442 443
#if ISC_MEM_FILL
	if (ret != NULL)
		memset(ret, 0xbe, new_size); /* Mnemonic for "beef". */
#endif

Bob Halley's avatar
base  
Bob Halley committed
444 445 446 447
	return (ret);
}

void
Bob Halley's avatar
Bob Halley committed
448
__isc_mem_put(isc_mem_t *ctx, void *mem, size_t size)
Michael Graff's avatar
Michael Graff committed
449
{
Bob Halley's avatar
base  
Bob Halley committed
450
	REQUIRE(size > 0);
Bob Halley's avatar
Bob Halley committed
451
	REQUIRE(VALID_CONTEXT(ctx));
Michael Graff's avatar
Michael Graff committed
452

Bob Halley's avatar
Bob Halley committed
453
	LOCK(&ctx->lock);
Bob Halley's avatar
Bob Halley committed
454
	mem_putunlocked(ctx, mem, size);
Michael Graff's avatar
Michael Graff committed
455 456 457 458
	UNLOCK(&ctx->lock);
}

static inline void
Bob Halley's avatar
Bob Halley committed
459
mem_putunlocked(isc_mem_t *ctx, void *mem, size_t size)
Michael Graff's avatar
Michael Graff committed
460 461
{
	size_t new_size = quantize(size);
Bob Halley's avatar
base  
Bob Halley committed
462

463
#if ISC_MEM_FILL
Bob Halley's avatar
Bob Halley committed
464
	memset(mem, 0xde, new_size); /* Mnemonic for "dead". */
465 466
#endif

Bob Halley's avatar
base  
Bob Halley committed
467 468
	if (size == ctx->max_size || new_size >= ctx->max_size) {
		/* memput() called on something beyond our upper limit */
469
		(ctx->memfree)(ctx->arg, mem);
Bob Halley's avatar
base  
Bob Halley committed
470 471
		INSIST(ctx->stats[ctx->max_size].gets != 0);
		ctx->stats[ctx->max_size].gets--;
Bob Halley's avatar
Bob Halley committed
472 473
		INSIST(size <= ctx->total);
		ctx->total -= size;
Michael Graff's avatar
Michael Graff committed
474
		return;
Bob Halley's avatar
base  
Bob Halley committed
475 476 477
	}

	/* The free list uses the "rounded-up" size "new_size": */
Bob Halley's avatar
Bob Halley committed
478 479
	((element *)mem)->next = ctx->freelists[new_size];
	ctx->freelists[new_size] = (element *)mem;
Bob Halley's avatar
base  
Bob Halley committed
480 481 482 483 484 485 486 487 488 489 490 491 492

	/* 
	 * The stats[] uses the _actual_ "size" requested by the
	 * caller, with the caveat (in the code above) that "size" >= the
	 * max. size (max_size) ends up getting recorded as a call to
	 * max_size.
	 */
	INSIST(ctx->stats[size].gets != 0);
	ctx->stats[size].gets--;
	ctx->stats[new_size].freefrags++;
}

void *
493
__isc_mem_getdebug(isc_mem_t *ctx, size_t size, const char *file, int line) {
Bob Halley's avatar
base  
Bob Halley committed
494
	void *ptr;
Bob Halley's avatar
Bob Halley committed
495

Bob Halley's avatar
Bob Halley committed
496
	ptr = __isc_mem_get(ctx, size);
Bob Halley's avatar
base  
Bob Halley committed
497
	fprintf(stderr, "%s:%d: mem_get(%p, %lu) -> %p\n", file, line,
Bob Halley's avatar
Bob Halley committed
498
		ctx, (unsigned long)size, ptr);
Bob Halley's avatar
base  
Bob Halley committed
499 500 501 502
	return (ptr);
}

void
503
__isc_mem_putdebug(isc_mem_t *ctx, void *ptr, size_t size, const char *file,
Bob Halley's avatar
Bob Halley committed
504
		 int line)
Bob Halley's avatar
base  
Bob Halley committed
505 506
{
	fprintf(stderr, "%s:%d: mem_put(%p, %p, %lu)\n", file, line, 
Bob Halley's avatar
Bob Halley committed
507
		ctx, ptr, (unsigned long)size);
Bob Halley's avatar
Bob Halley committed
508
	__isc_mem_put(ctx, ptr, size);
Bob Halley's avatar
base  
Bob Halley committed
509 510 511 512 513 514
}

/*
 * Print the stats[] on the stream "out" with suitable formatting.
 */
void
Michael Graff's avatar
Michael Graff committed
515 516
isc_mem_stats(isc_mem_t *ctx, FILE *out)
{
Bob Halley's avatar
base  
Bob Halley committed
517
	size_t i;
Michael Graff's avatar
Michael Graff committed
518 519
	const struct stats *s;
	const isc_mempool_t *pool;
Bob Halley's avatar
base  
Bob Halley committed
520

Bob Halley's avatar
Bob Halley committed
521 522
	REQUIRE(VALID_CONTEXT(ctx));
	LOCK(&ctx->lock);
Bob Halley's avatar
base  
Bob Halley committed
523

Michael Graff's avatar
Michael Graff committed
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
	if (ctx->freelists != NULL) {
		for (i = 1; i <= ctx->max_size; i++) {
			s = &ctx->stats[i];

			if (s->totalgets == 0 && s->gets == 0)
				continue;
			fprintf(out, "%s%5d: %11lu gets, %11lu rem",
				(i == ctx->max_size) ? ">=" : "  ",
				i, s->totalgets, s->gets);
			if (s->blocks != 0)
				fprintf(out, " (%lu bl, %lu ff)",
					s->blocks, s->freefrags);
			fputc('\n', out);
		}
	}

Michael Graff's avatar
Michael Graff committed
540 541 542 543 544 545 546
	/*
	 * Note that since a pool can be locked now, these stats might be
	 * somewhat off if the pool is in active use at the time the stats
	 * are dumped.  The link fields are protected by the isc_mem_t's
	 * lock, however, so walking this list and extracting integers from
	 * stats fields is always safe.
	 */
Michael Graff's avatar
Michael Graff committed
547 548 549
	pool = ISC_LIST_HEAD(ctx->pools);
	if (pool != NULL) {
		fprintf(out, "[Pool statistics]\n");
Michael Graff's avatar
Michael Graff committed
550
		fprintf(out, "%10s %10s %10s %10s %10s %10s %10s %1s\n",
Michael Graff's avatar
Michael Graff committed
551
			"size", "maxalloc", "allocated", "freecount",
Michael Graff's avatar
Michael Graff committed
552
			"freemax", "fillcount", "gets", "L");
Michael Graff's avatar
Michael Graff committed
553 554
	}
	while (pool != NULL) {
Michael Graff's avatar
Michael Graff committed
555
		fprintf(out, "%10u %10u %10u %10u %10u %10u %10u %s\n",
Michael Graff's avatar
Michael Graff committed
556 557
			pool->size, pool->maxalloc, pool->allocated,
			pool->freecount, pool->freemax, pool->fillcount,
Michael Graff's avatar
Michael Graff committed
558 559
			pool->gets,
			(pool->lock == NULL ? "N" : "Y"));
Michael Graff's avatar
Michael Graff committed
560
		pool = ISC_LIST_NEXT(pool, link);
Bob Halley's avatar
base  
Bob Halley committed
561 562
	}

Bob Halley's avatar
Bob Halley committed
563
	UNLOCK(&ctx->lock);
Bob Halley's avatar
base  
Bob Halley committed
564 565
}

Bob Halley's avatar
Bob Halley committed
566
isc_boolean_t
567
isc_mem_valid(isc_mem_t *ctx, void *ptr) {
Bob Halley's avatar
Bob Halley committed
568
	unsigned char *cp = ptr;
Bob Halley's avatar
Bob Halley committed
569
	isc_boolean_t result = ISC_FALSE;
Bob Halley's avatar
base  
Bob Halley committed
570

Bob Halley's avatar
Bob Halley committed
571 572
	REQUIRE(VALID_CONTEXT(ctx));
	LOCK(&ctx->lock);
Bob Halley's avatar
base  
Bob Halley committed
573 574

	if (ctx->lowest != NULL && cp >= ctx->lowest && cp <= ctx->highest)
Bob Halley's avatar
Bob Halley committed
575
		result = ISC_TRUE;
Bob Halley's avatar
base  
Bob Halley committed
576

Bob Halley's avatar
Bob Halley committed
577
	UNLOCK(&ctx->lock);
Bob Halley's avatar
base  
Bob Halley committed
578

Bob Halley's avatar
Bob Halley committed
579
	return (result);
Bob Halley's avatar
base  
Bob Halley committed
580 581 582 583 584 585 586
}

/*
 * Replacements for malloc() and free().
 */

void *
587
isc_mem_allocate(isc_mem_t *ctx, size_t size) {
Bob Halley's avatar
Bob Halley committed
588
	size_info *si;
Bob Halley's avatar
base  
Bob Halley committed
589 590

	size += ALIGNMENT_SIZE;
Bob Halley's avatar
Bob Halley committed
591
	si = isc_mem_get(ctx, size);
Bob Halley's avatar
base  
Bob Halley committed
592 593 594 595 596 597 598
	if (si == NULL)
		return (NULL);
	si->size = size;
	return (&si[1]);
}

void
599
isc_mem_free(isc_mem_t *ctx, void *ptr) {
Bob Halley's avatar
Bob Halley committed
600
	size_info *si;
Bob Halley's avatar
base  
Bob Halley committed
601

Bob Halley's avatar
Bob Halley committed
602
	si = &(((size_info *)ptr)[-1]);
Bob Halley's avatar
Bob Halley committed
603
	isc_mem_put(ctx, si, si->size);
Bob Halley's avatar
base  
Bob Halley committed
604 605
}

Bob Halley's avatar
Bob Halley committed
606 607 608 609
/*
 * Other useful things.
 */

Bob Halley's avatar
Bob Halley committed
610 611 612 613 614 615 616 617 618 619 620 621 622 623
char *
isc_mem_strdup(isc_mem_t *mctx, const char *s) {
	size_t len;
	char *ns;

	len = strlen(s);
	ns = isc_mem_allocate(mctx, len + 1);
	if (ns == NULL)
		return (NULL);
	strncpy(ns, s, len + 1);
	
	return (ns);
}

624 625 626 627 628 629 630 631 632 633 634 635
isc_boolean_t
isc_mem_destroy_check(isc_mem_t *mctx, isc_boolean_t flag) {
	isc_boolean_t oldval;

	INSIST(mctx != NULL);

	oldval = mctx->checkfree;
	mctx->checkfree = flag;
	return (oldval);
}


636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663
/*
 * Quotas
 */

void
isc_mem_setquota(isc_mem_t *ctx, size_t quota) {
	REQUIRE(VALID_CONTEXT(ctx));
	LOCK(&ctx->lock);

	ctx->quota = quota;

	UNLOCK(&ctx->lock);
}

size_t
isc_mem_getquota(isc_mem_t *ctx) {
	size_t quota;

	REQUIRE(VALID_CONTEXT(ctx));
	LOCK(&ctx->lock);

	quota = ctx->quota;

	UNLOCK(&ctx->lock);

	return (quota);
}

Bob Halley's avatar
Bob Halley committed
664 665
#ifdef ISC_MEMCLUSTER_LEGACY

Bob Halley's avatar
base  
Bob Halley committed
666 667 668 669
/*
 * Public Legacy.
 */

670
static isc_mem_t *default_context = NULL;
Bob Halley's avatar
Bob Halley committed
671

Bob Halley's avatar
base  
Bob Halley committed
672 673 674 675 676
int
meminit(size_t init_max_size, size_t target_size) {
	/* need default_context lock here */
	if (default_context != NULL)
		return (-1);
Bob Halley's avatar
Bob Halley committed
677
	return (isc_mem_create(init_max_size, target_size, &default_context));
Bob Halley's avatar
base  
Bob Halley committed
678 679
}

680
isc_mem_t *
Bob Halley's avatar
base  
Bob Halley committed
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
mem_default_context(void) {
	/* need default_context lock here */
	if (default_context == NULL && meminit(0, 0) == -1)
		return (NULL);
	return (default_context);
}

void *
__memget(size_t size) {
	/* need default_context lock here */
	if (default_context == NULL && meminit(0, 0) == -1)
		return (NULL);
	return (__mem_get(default_context, size));
}

void
__memput(void *mem, size_t size) {
	/* need default_context lock here */
	REQUIRE(default_context != NULL);
	__mem_put(default_context, mem, size);
}

void *
__memget_debug(size_t size, const char *file, int line) {
	void *ptr;
	ptr = __memget(size);
	fprintf(stderr, "%s:%d: memget(%lu) -> %p\n", file, line,
Bob Halley's avatar
Bob Halley committed
708
		(unsigned long)size, ptr);
Bob Halley's avatar
base  
Bob Halley committed
709 710 711 712 713 714
	return (ptr);
}

void
__memput_debug(void *ptr, size_t size, const char *file, int line) {
	fprintf(stderr, "%s:%d: memput(%p, %lu)\n", file, line, 
Bob Halley's avatar
Bob Halley committed
715
		ptr, (unsigned long)size);
Bob Halley's avatar
base  
Bob Halley committed
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731
	__memput(ptr, size);
}

int
memvalid(void *ptr) {
	/* need default_context lock here */
	REQUIRE(default_context != NULL);
	return (mem_valid(default_context, ptr));
}

void
memstats(FILE *out) {
	/* need default_context lock here */
	REQUIRE(default_context != NULL);
	mem_stats(default_context, out);
}
Bob Halley's avatar
Bob Halley committed
732 733

#endif /* ISC_MEMCLUSTER_LEGACY */
Michael Graff's avatar
Michael Graff committed
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761


/*
 * Memory pool stuff
 */


#if 0
/*
 * Free all but "n" items from the pool's free list.  If n == 0, all items
 * will be returned to the mctx.
 */
static void
mempool_release(isc_mempool_t *mpctx, unsigned int n)
{
	isc_mem_t *mctx;
	element *item;
	element *next;
	unsigned int count;

	mctx = mpctx->mctx;

	if (mpctx->freecount <= n)
		return;

	INSIST(mpctx->items != NULL);
	item = mpctx->items;
	for (count = 0 ; count < n ; count++) {
Michael Graff's avatar
Michael Graff committed
762
		item = item->next;
Michael Graff's avatar
Michael Graff committed
763 764 765 766 767 768 769 770 771
		INSIST(item != NULL);
	}

	/*
	 * All remaining items are to be freed.  Lock the context once,
	 * free them all, and unlock the context.
	 */
	LOCK(&mctx->lock);
	do {
Michael Graff's avatar
Michael Graff committed
772
		next = item->next;
Michael Graff's avatar
Michael Graff committed
773 774 775 776 777 778 779 780 781 782 783
		mem_putunlocked(mctx, item, mpctx->size);
		INSIST(mpctx->freecount > 0);
		mpctx->freecount--;
		item = next;
	} while (item != NULL);
	UNLOCK(&mctx->lock);
}
#endif

/*
 * Release all items on the free list.  No locking is done, the memory
Michael Graff's avatar
Michael Graff committed
784
 * context must be locked, and the pool if needed.
Michael Graff's avatar
Michael Graff committed
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
 */
static void
mempool_releaseall(isc_mempool_t *mpctx)
{
	isc_mem_t *mctx;
	element *item;
	element *next;

	mctx = mpctx->mctx;

	if (mpctx->freecount == 0)
		return;

	INSIST(mpctx->items != NULL);
	item = mpctx->items;

	do {
Michael Graff's avatar
Michael Graff committed
802
		next = item->next;
Bob Halley's avatar
Bob Halley committed
803
		mem_putunlocked(mctx, item, mpctx->size);
Michael Graff's avatar
Michael Graff committed
804 805 806 807 808 809 810
		INSIST(mpctx->freecount > 0);
		mpctx->freecount--;
		item = next;
	} while (item != NULL);
}

isc_result_t
Michael Graff's avatar
Michael Graff committed
811
isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp)
Michael Graff's avatar
Michael Graff committed
812 813 814 815
{
	isc_mempool_t *mpctx;

	REQUIRE(VALID_CONTEXT(mctx));
Michael Graff's avatar
Michael Graff committed
816
	REQUIRE(size > 0);
Michael Graff's avatar
Michael Graff committed
817 818 819 820 821 822 823 824
	REQUIRE(mpctxp != NULL && *mpctxp == NULL);

	/*
	 * Allocate space for this pool, initialize values, and if all works
	 * well, attach to the memory context.
	 */
	LOCK(&mctx->lock);

Bob Halley's avatar
Bob Halley committed
825
	mpctx = mem_getunlocked(mctx, sizeof(isc_mempool_t));
Michael Graff's avatar
Michael Graff committed
826 827 828 829 830 831
	if (mpctx == NULL) {
		UNLOCK(&mctx->lock);
		return (ISC_R_NOMEMORY);
	}

	mpctx->magic = MEMPOOL_MAGIC;
Michael Graff's avatar
Michael Graff committed
832
	mpctx->lock = NULL;
Michael Graff's avatar
Michael Graff committed
833
	mpctx->mctx = mctx;
Michael Graff's avatar
Michael Graff committed
834
	mpctx->size = size;
Michael Graff's avatar
Michael Graff committed
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856
	mpctx->maxalloc = UINT_MAX;
	mpctx->allocated = 0;
	mpctx->freecount = 0;
	mpctx->freemax = 1;
	mpctx->fillcount = 1;
	mpctx->gets = 0;
	mpctx->items = NULL;

	*mpctxp = mpctx;

	ISC_LIST_APPEND(mctx->pools, mpctx, link);

	UNLOCK(&mctx->lock);

	return (ISC_R_SUCCESS);
}

void
isc_mempool_destroy(isc_mempool_t **mpctxp)
{
	isc_mempool_t *mpctx;
	isc_mem_t *mctx;
Michael Graff's avatar
Michael Graff committed
857
	isc_mutex_t *lock;
Michael Graff's avatar
Michael Graff committed
858 859 860 861 862 863 864 865

	REQUIRE(mpctxp != NULL);
	mpctx = *mpctxp;
	REQUIRE(VALID_MEMPOOL(mpctx));
	REQUIRE(mpctx->allocated == 0);

	mctx = mpctx->mctx;

Michael Graff's avatar
Michael Graff committed
866 867 868 869 870
	lock = mpctx->lock;

	if (lock != NULL)
		LOCK(lock);

Michael Graff's avatar
Michael Graff committed
871 872 873 874 875 876 877 878 879 880 881 882 883 884
	LOCK(&mctx->lock);

	/*
	 * Return any items on the free list
	 */
	mempool_releaseall(mpctx);

	/*
	 * Remove our linked list entry from the memory context.
	 */
	ISC_LIST_UNLINK(mctx->pools, mpctx, link);
	
	mpctx->magic = 0;

Bob Halley's avatar
Bob Halley committed
885
	mem_putunlocked(mpctx->mctx, mpctx, sizeof(isc_mempool_t));
Michael Graff's avatar
Michael Graff committed
886 887 888

	UNLOCK(&mctx->lock);

Michael Graff's avatar
Michael Graff committed
889 890 891
	if (lock != NULL)
		UNLOCK(lock);

Michael Graff's avatar
Michael Graff committed
892 893 894
	*mpctxp = NULL;
}

Michael Graff's avatar
Michael Graff committed
895 896 897 898 899 900 901 902 903 904
void
isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock)
{
	REQUIRE(VALID_MEMPOOL(mpctx));
	REQUIRE(mpctx->lock == NULL);
	REQUIRE(lock != NULL);

	mpctx->lock = lock;
}

Michael Graff's avatar
Michael Graff committed
905 906 907 908 909 910 911 912 913 914 915
void *
__isc_mempool_get(isc_mempool_t *mpctx)
{
	element *item;
	isc_mem_t *mctx;
	unsigned int i;

	REQUIRE(VALID_MEMPOOL(mpctx));

	mctx = mpctx->mctx;

Michael Graff's avatar
Michael Graff committed
916 917 918
	if (mpctx->lock != NULL)
		LOCK(mpctx->lock);

Michael Graff's avatar
Michael Graff committed
919 920 921
	/*
	 * Don't let the caller go over quota
	 */
Michael Graff's avatar
Michael Graff committed
922 923 924 925
	if (mpctx->allocated >= mpctx->maxalloc) {
		item = NULL;
		goto out;
	}
Michael Graff's avatar
Michael Graff committed
926 927 928 929 930 931 932 933 934 935 936

	/*
	 * if we have a free list item, return the first here
	 */
	item = mpctx->items;
	if (item != NULL) {
		mpctx->items = item->next;
		INSIST(mpctx->freecount > 0);
		mpctx->freecount--;
		mpctx->gets++;
		mpctx->allocated++;
Michael Graff's avatar
Michael Graff committed
937
		goto out;
Michael Graff's avatar
Michael Graff committed
938 939 940 941 942 943 944 945
	}

	/*
	 * We need to dip into the well.  Lock the memory context here and
	 * fill up our free list.
	 */
	LOCK(&mctx->lock);
	for (i = 0 ; i < mpctx->fillcount ; i++) {
Bob Halley's avatar
Bob Halley committed
946
		item = mem_getunlocked(mctx, mpctx->size);
Michael Graff's avatar
Michael Graff committed
947 948 949 950 951 952 953 954 955 956 957 958 959
		if (item == NULL)
			break;
		item->next = mpctx->items;
		mpctx->items = item;
		mpctx->freecount++;
	}
	UNLOCK(&mctx->lock);

	/*
	 * If we didn't get any items, return NULL.
	 */
	item = mpctx->items;
	if (item == NULL)
Michael Graff's avatar
Michael Graff committed
960
		goto out;
Michael Graff's avatar
Michael Graff committed
961 962 963 964 965

	mpctx->items = item->next;
	mpctx->freecount--;
	mpctx->gets++;
	mpctx->allocated++;
Michael Graff's avatar
Michael Graff committed
966 967 968 969 970

 out:
	if (mpctx->lock != NULL)
		UNLOCK(mpctx->lock);

Michael Graff's avatar
Michael Graff committed
971 972 973 974 975 976 977 978 979 980 981 982 983 984
	return (item);
}

void
__isc_mempool_put(isc_mempool_t *mpctx, void *mem)
{
	isc_mem_t *mctx;
	element *item;

	REQUIRE(VALID_MEMPOOL(mpctx));
	REQUIRE(mem != NULL);

	mctx = mpctx->mctx;

Michael Graff's avatar
Michael Graff committed
985 986 987
	if (mpctx->lock != NULL)
		LOCK(mpctx->lock);

Michael Graff's avatar
Michael Graff committed
988 989 990 991 992 993 994
	INSIST(mpctx->allocated > 0);
	mpctx->allocated--;

	/*
	 * If our free list is full, return this to the mctx directly.
	 */
	if (mpctx->freecount >= mpctx->freemax) {
Bob Halley's avatar
Bob Halley committed
995
		__isc_mem_put(mctx, mem, mpctx->size);
Michael Graff's avatar
Michael Graff committed
996 997
		if (mpctx->lock != NULL)
			UNLOCK(mpctx->lock);
Michael Graff's avatar
Michael Graff committed
998 999 1000 1001 1002 1003 1004 1005 1006 1007
		return;
	}

	/*
	 * Otherwise, attach it to our free list and bump the counter.
	 */
	mpctx->freecount++;
	item = (element *)mem;
	item->next = mpctx->items;
	mpctx->items = item;
Michael Graff's avatar
Michael Graff committed
1008 1009 1010

	if (mpctx->lock != NULL)
		UNLOCK(mpctx->lock);
Michael Graff's avatar
Michael Graff committed
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
}

void *
__isc_mempool_getdebug(isc_mempool_t *mpctx,
		       const char *file, int line)
{
	void *ptr;

	ptr = __isc_mempool_get(mpctx);
	fprintf(stderr, "%s:%d: mempool_get(%p) -> %p\n", file, line,
		mpctx, ptr);

	return (ptr);
}

void
__isc_mempool_putdebug(isc_mempool_t *mpctx, void *ptr,
		       const char *file, int line)
{
	fprintf(stderr, "%s:%d: mempool_put(%p, %p)\n", file, line, 
		mpctx, ptr);
	__isc_mempool_put(mpctx, ptr);
}

/*
 * Quotas
 */

void
isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit)
{
	REQUIRE(VALID_MEMPOOL(mpctx));

Michael Graff's avatar
Michael Graff committed
1044 1045 1046
	if (mpctx->lock != NULL)
		LOCK(mpctx->lock);

Michael Graff's avatar
Michael Graff committed
1047
	mpctx->freemax = limit;
Michael Graff's avatar
Michael Graff committed
1048 1049 1050

	if (mpctx->lock != NULL)
		UNLOCK(mpctx->lock);
Michael Graff's avatar
Michael Graff committed
1051 1052 1053 1054 1055
}

unsigned int
isc_mempool_getfreemax(isc_mempool_t *mpctx)
{
Michael Graff's avatar
Michael Graff committed
1056 1057
	unsigned int freemax;

Michael Graff's avatar
Michael Graff committed
1058 1059
	REQUIRE(VALID_MEMPOOL(mpctx));

Michael Graff's avatar
Michael Graff committed
1060 1061 1062 1063 1064 1065 1066 1067 1068
	if (mpctx->lock != NULL)
		LOCK(mpctx->lock);

	freemax = mpctx->freemax;

	if (mpctx->lock != NULL)
		UNLOCK(mpctx->lock);

	return (freemax);
Michael Graff's avatar
Michael Graff committed
1069 1070 1071 1072 1073
}

unsigned int
isc_mempool_getfreecount(isc_mempool_t *mpctx)
{
Michael Graff's avatar
Michael Graff committed
1074 1075
	unsigned int freecount;

Michael Graff's avatar
Michael Graff committed
1076 1077
	REQUIRE(VALID_MEMPOOL(mpctx));

Michael Graff's avatar
Michael Graff committed
1078 1079 1080 1081 1082 1083 1084 1085 1086
	if (mpctx->lock != NULL)
		LOCK(mpctx->lock);

	freecount = mpctx->freecount;

	if (mpctx->lock != NULL)
		UNLOCK(mpctx->lock);

	return (freecount);
Michael Graff's avatar
Michael Graff committed
1087 1088 1089 1090 1091 1092 1093 1094 1095
}

void
isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit)
{
	REQUIRE(limit > 0);

	REQUIRE(VALID_MEMPOOL(mpctx));

Michael Graff's avatar
Michael Graff committed
1096 1097 1098
	if (mpctx->lock != NULL)
		LOCK(mpctx->lock);

Michael Graff's avatar
Michael Graff committed
1099
	mpctx->maxalloc = limit;
Michael Graff's avatar
Michael Graff committed
1100 1101 1102

	if (mpctx->lock != NULL)
		UNLOCK(mpctx->lock);
Michael Graff's avatar
Michael Graff committed
1103 1104 1105 1106 1107
}

unsigned int
isc_mempool_getmaxalloc(isc_mempool_t *mpctx)
{
Michael Graff's avatar
Michael Graff committed
1108 1109
	unsigned int maxalloc;

Michael Graff's avatar
Michael Graff committed
1110 1111
	REQUIRE(VALID_MEMPOOL(mpctx));

Michael Graff's avatar
Michael Graff committed
1112 1113 1114 1115 1116 1117 1118 1119 1120
	if (mpctx->lock != NULL)
		LOCK(mpctx->lock);

	maxalloc = mpctx->maxalloc;

	if (mpctx->lock != NULL)
		UNLOCK(mpctx->lock);

	return (maxalloc);
Michael Graff's avatar
Michael Graff committed
1121 1122 1123 1124 1125
}

unsigned int
isc_mempool_getallocated(isc_mempool_t *mpctx)
{
Michael Graff's avatar
Michael Graff committed
1126 1127
	unsigned int allocated;

Michael Graff's avatar
Michael Graff committed
1128 1129
	REQUIRE(VALID_MEMPOOL(mpctx));

Michael Graff's avatar
Michael Graff committed
1130 1131 1132 1133 1134 1135 1136 1137 1138
	if (mpctx->lock != NULL)
		LOCK(mpctx->lock);

	allocated = mpctx->allocated;

	if (mpctx->lock != NULL)
		UNLOCK(mpctx->lock);

	return (allocated);
Michael Graff's avatar
Michael Graff committed
1139 1140 1141