mem.c revision f859f35d857ba99d0fff548db6d568499a58de63
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Copyright (C) 1997, 1998, 1999 Internet Software Consortium.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * copyright notice and this permission notice appear in all copies.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * SOFTWARE.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#include <config.h>
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#include <stdio.h>
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#include <stdlib.h>
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#include <stddef.h>
f80ea74e1984e0b1dbe48dd86ecdd3a2380393cbBob Halley#include <string.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <limits.h>
fc8a6561cbb0a1fea849950a3217aacd3b8f1eacDavid Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/assertions.h>
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson#include <isc/error.h>
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#include <isc/mem.h>
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#ifndef ISC_SINGLETHREADED
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#include <isc/mutex.h>
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#include "util.h"
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews#else
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#define LOCK(l)
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington#define UNLOCK(l)
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews#endif
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews#ifndef ISC_MEM_FILL
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence /*
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * XXXMPA
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * We want this on during development to catch:
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * 1. some reference after free bugs.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * 2. some failure to initalise bugs.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#define ISC_MEM_FILL 1
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#endif
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein#ifndef ISC_MEMPOOL_NAMES
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff/*
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * During development it is nice to be able to see names associated with
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * memory pools.
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#define ISC_MEMPOOL_NAMES 1
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence#endif
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson/*
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * Constants.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#define DEF_MAX_SIZE 1100
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#define DEF_MEM_TARGET 4096
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence#define ALIGNMENT_SIZE 8
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#define NUM_BASIC_BLOCKS 64 /* must be > 1 */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#define TABLE_INCREMENT 1024
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson/*
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * Types.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatertypedef struct {
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson void * next;
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson} element;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencetypedef struct {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff * This structure must be ALIGNMENT_SIZE bytes.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff */
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson union {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein size_t size;
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence char bytes[ALIGNMENT_SIZE];
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence } u;
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence} size_info;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstruct stats {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned long gets;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned long totalgets;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned long blocks;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned long freefrags;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater};
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#define MEM_MAGIC 0x4D656d43U /* MemC. */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#define VALID_CONTEXT(c) ((c) != NULL && (c)->magic == MEM_MAGIC)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstruct isc_mem {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned int magic;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mutex_t lock;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_memalloc_t memalloc;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_memfree_t memfree;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater void * arg;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t max_size;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t mem_target;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson element ** freelists;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson element * basic_blocks;
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein unsigned char ** basic_table;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence unsigned int basic_table_count;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson unsigned int basic_table_size;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson unsigned char * lowest;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson unsigned char * highest;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_boolean_t checkfree;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater struct stats * stats;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t quota;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t total;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST(isc_mempool_t) pools;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater};
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#define MEMPOOL_MAGIC 0x4D454d70U /* MEMp. */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#define VALID_MEMPOOL(c) ((c) != NULL && (c)->magic == MEMPOOL_MAGIC)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstruct isc_mempool {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* always unlocked */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned int magic; /* magic number */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mutex_t *lock; /* optional lock */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_t *mctx; /* our memory context */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* locked via the memory context's lock */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LINK(isc_mempool_t) link; /* next pool in this mem context */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* optionally locked from here down */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater element *items; /* low water item list */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff size_t size; /* size of each item on this pool */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff unsigned int maxalloc; /* max number of items allowed */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff unsigned int allocated; /* # of items currently given out */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned int freecount; /* # of items on reserved list */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned int freemax; /* # of items allowed on free list */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff unsigned int fillcount; /* # of items to fetch on each fill */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson /* Stats only. */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson unsigned int gets; /* # of requests to this pool */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson /* Debugging only. */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#if ISC_MEMPOOL_NAMES
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson char name[16]; /* printed name in stats reports */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson#endif
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson};
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater/*
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson * Forward.
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonstatic inline size_t quantize(size_t);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonstatic inline void mem_putunlocked(isc_mem_t *, void *, size_t);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonstatic inline void * mem_getunlocked(isc_mem_t *, size_t);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff/*
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * Private Inline-able.
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrewsstatic inline size_t
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffquantize(size_t size) {
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff int temp;
4c1817c29c78d533eae9f4bdf8c9b4d5c90ebfdbMark Andrews
4c1817c29c78d533eae9f4bdf8c9b4d5c90ebfdbMark Andrews /*
4c1817c29c78d533eae9f4bdf8c9b4d5c90ebfdbMark Andrews * Round up the result in order to get a size big
4c1817c29c78d533eae9f4bdf8c9b4d5c90ebfdbMark Andrews * enough to satisfy the request and be aligned on ALIGNMENT_SIZE
4c1817c29c78d533eae9f4bdf8c9b4d5c90ebfdbMark Andrews * byte boundaries.
4c1817c29c78d533eae9f4bdf8c9b4d5c90ebfdbMark Andrews */
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews temp = size + (ALIGNMENT_SIZE - 1);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (temp - temp % ALIGNMENT_SIZE);
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Private.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstatic void *
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterdefault_memalloc(void *arg, size_t size) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (void)arg;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (malloc(size));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstatic void
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterdefault_memfree(void *arg, void *ptr) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (void)arg;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater free(ptr);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Public.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_result_t
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_createx(size_t init_max_size, size_t target_size,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_memalloc_t memalloc, isc_memfree_t memfree, void *arg,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_t **ctxp)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater{
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_t *ctx;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(ctxp != NULL && *ctxp == NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(memalloc != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(memfree != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx = (memalloc)(arg, sizeof *ctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx == NULL)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ISC_R_NOMEMORY);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (init_max_size == 0)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->max_size = DEF_MAX_SIZE;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater else
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->max_size = init_max_size;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (target_size == 0)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->mem_target = DEF_MEM_TARGET;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater else
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->mem_target = target_size;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->memalloc = memalloc;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->memfree = memfree;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->arg = arg;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->freelists = (memalloc)(arg, ctx->max_size * sizeof (element *));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->freelists == NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (memfree)(arg, ctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ISC_R_NOMEMORY);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->checkfree = ISC_TRUE;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater memset(ctx->freelists, 0,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->max_size * sizeof (element *));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->stats = (memalloc)(arg,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (ctx->max_size+1) * sizeof (struct stats));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->stats == NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (memfree)(arg, ctx->freelists);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (memfree)(arg, ctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ISC_R_NOMEMORY);
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews }
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff memset(ctx->stats, 0, (ctx->max_size + 1) * sizeof (struct stats));
261a6a1f7d95eaf0cd882f3123dcfd775517a54fMark Andrews ctx->basic_blocks = NULL;
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington ctx->basic_table = NULL;
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington ctx->basic_table_count = 0;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->basic_table_size = 0;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->lowest = NULL;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->highest = NULL;
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington if (isc_mutex_init(&ctx->lock) != ISC_R_SUCCESS) {
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington (memfree)(arg, ctx->stats);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence (memfree)(arg, ctx->freelists);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson (memfree)(arg, ctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNEXPECTED_ERROR(__FILE__, __LINE__,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "isc_mutex_init() failed");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ISC_R_UNEXPECTED);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->quota = 0;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->total = 0;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->magic = MEM_MAGIC;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_INIT(ctx->pools);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater *ctxp = ctx;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ISC_R_SUCCESS);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_result_t
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_create(size_t init_max_size, size_t target_size,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_t **ctxp)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater{
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (isc_mem_createx(init_max_size, target_size,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater default_memalloc, default_memfree, NULL,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctxp));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_destroy(isc_mem_t **ctxp) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned int i;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_t *ctx;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(ctxp != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx = *ctxp;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(VALID_CONTEXT(ctx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->magic = 0;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(ISC_LIST_EMPTY(ctx->pools));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->checkfree) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater for (i = 0; i <= ctx->max_size; i++)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(ctx->stats[i].gets == 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#if 0 /* XXX brister debugging */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater for (i = 0; i < ctx->basic_table_count; i++)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater memset(ctx->basic_table[i], 0x0,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater NUM_BASIC_BLOCKS * ctx->mem_target);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#endif
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater for (i = 0; i < ctx->basic_table_count; i++)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (ctx->memfree)(ctx->arg, ctx->basic_table[i]);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (ctx->memfree)(ctx->arg, ctx->freelists);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (ctx->memfree)(ctx->arg, ctx->stats);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (ctx->memfree)(ctx->arg, ctx->basic_table);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (void)isc_mutex_destroy(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (ctx->memfree)(ctx->arg, ctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater *ctxp = NULL;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_result_t
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_restore(isc_mem_t *ctx) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_result_t result;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = isc_mutex_init(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (result != ISC_R_SUCCESS)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->magic = 0;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (result);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstatic void
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatermore_basic_blocks(isc_mem_t *ctx) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater void *new;
7618f0551eb745354ee695907e568b0be1f2c8f5Andreas Gustafsson unsigned char *curr, *next;
7618f0551eb745354ee695907e568b0be1f2c8f5Andreas Gustafsson unsigned char *first, *last;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned char **table;
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington unsigned int table_size;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t increment;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater int i;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* Require: we hold the context lock. */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /*
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington * Did we hit the quota for this context?
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington increment = NUM_BASIC_BLOCKS * ctx->mem_target;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->quota != 0 && ctx->total + increment > ctx->quota)
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington return;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
7618f0551eb745354ee695907e568b0be1f2c8f5Andreas Gustafsson INSIST(ctx->basic_table_count <= ctx->basic_table_size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->basic_table_count == ctx->basic_table_size) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater table_size = ctx->basic_table_size + TABLE_INCREMENT;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater table = (ctx->memalloc)(ctx->arg,
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson table_size * sizeof (unsigned char *));
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson if (table == NULL)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence return;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson if (ctx->basic_table_size != 0) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater memcpy(table, ctx->basic_table,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->basic_table_size *
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson sizeof (unsigned char *));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (ctx->memfree)(ctx->arg, ctx->basic_table);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews ctx->basic_table = table;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->basic_table_size = table_size;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater new = (ctx->memalloc)(ctx->arg, NUM_BASIC_BLOCKS * ctx->mem_target);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson if (new == NULL)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return;
ce3c351d815569455892c30dc78d8c2e85ec1076Andreas Gustafsson ctx->total += increment;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->basic_table[ctx->basic_table_count] = new;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->basic_table_count++;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater curr = new;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson next = curr + ctx->mem_target;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater for (i = 0; i < (NUM_BASIC_BLOCKS - 1); i++) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ((element *)curr)->next = next;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson curr = next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater next += ctx->mem_target;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * curr is now pointing at the last block in the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * array.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ((element *)curr)->next = NULL;
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington first = new;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater last = first + NUM_BASIC_BLOCKS * ctx->mem_target - 1;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (first < ctx->lowest || ctx->lowest == NULL)
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington ctx->lowest = first;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (last > ctx->highest)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->highest = last;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->basic_blocks = new;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence__isc_mem_get(isc_mem_t *ctx, size_t size)
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson{
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson void *ret;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson REQUIRE(size > 0);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson REQUIRE(VALID_CONTEXT(ctx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater LOCK(&ctx->lock);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson ret = mem_getunlocked(ctx, size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNLOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ret);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonstatic inline void *
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonmem_getunlocked(isc_mem_t *ctx, size_t size)
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson{
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson size_t new_size = quantize(size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater void *ret;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (size >= ctx->max_size || new_size >= ctx->max_size) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* memget() was called on something beyond our upper limit. */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->quota != 0 && ctx->total + size > ctx->quota) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ret = NULL;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater goto done;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ret = (ctx->memalloc)(ctx->arg, size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ret != NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->total += size;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->stats[ctx->max_size].gets++;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->stats[ctx->max_size].totalgets++;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If we don't set new_size to size, then the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * ISC_MEM_FILL code might write over bytes we
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * don't own.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater new_size = size;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater goto done;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * If there are no blocks in the free list for this size, get a chunk
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * of memory and then break it up into "new_size"-sized blocks, adding
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * them to the free list.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->freelists[new_size] == NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater int i, frags;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t total_size;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater void *new;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned char *curr, *next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->basic_blocks == NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater more_basic_blocks(ctx);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->basic_blocks == NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ret = NULL;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater goto done;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater total_size = ctx->mem_target;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson new = ctx->basic_blocks;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson ctx->basic_blocks = ctx->basic_blocks->next;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson frags = total_size / new_size;
b120e39deac3e9c323cdc7801ed2313f8ebbb744Andreas Gustafsson ctx->stats[new_size].blocks++;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->stats[new_size].freefrags += frags;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* Set up a linked-list of blocks of size "new_size". */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater curr = new;
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence next = curr + new_size;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater for (i = 0; i < (frags - 1); i++) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ((element *)curr)->next = next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater curr = next;
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence next += new_size;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson }
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson /* curr is now pointing at the last block in the array. */
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson ((element *)curr)->next = NULL;
4e1d3e67cdc76609bad5f0310ac48de10b442b9fMark Andrews ctx->freelists[new_size] = new;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* The free list uses the "rounded-up" size "new_size": */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ret = ctx->freelists[new_size];
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington ctx->freelists[new_size] = ctx->freelists[new_size]->next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * The stats[] uses the _actual_ "size" requested by the
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence * caller, with the caveat (in the code above) that "size" >= the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * max. size (max_size) ends up getting recorded as a call to
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * max_size.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->stats[size].gets++;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->stats[size].totalgets++;
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence ctx->stats[new_size].freefrags--;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson done:
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson#if ISC_MEM_FILL
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson if (ret != NULL)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater memset(ret, 0xbe, new_size); /* Mnemonic for "beef". */
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington#endif
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington return (ret);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrencevoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater__isc_mem_put(isc_mem_t *ctx, void *mem, size_t size)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater{
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(size > 0);
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence REQUIRE(VALID_CONTEXT(ctx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson LOCK(&ctx->lock);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson mem_putunlocked(ctx, mem, size);
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson UNLOCK(&ctx->lock);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellingtonstatic inline void
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatermem_putunlocked(isc_mem_t *ctx, void *mem, size_t size)
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson{
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t new_size = quantize(size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence if (size == ctx->max_size || new_size >= ctx->max_size) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* memput() called on something beyond our upper limit */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#if ISC_MEM_FILL
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater memset(mem, 0xde, size); /* Mnemonic for "dead". */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#endif
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence (ctx->memfree)(ctx->arg, mem);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(ctx->stats[ctx->max_size].gets != 0);
f0e246e271f84c6fe960a3c36703a56d1067431cBrian Wellington ctx->stats[ctx->max_size].gets--;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson INSIST(size <= ctx->total);
8f79820c6930ee5ef6b4a54f36d2559400bdf47dAndreas Gustafsson ctx->total -= size;
8f79820c6930ee5ef6b4a54f36d2559400bdf47dAndreas Gustafsson return;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#if ISC_MEM_FILL
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater memset(mem, 0xde, new_size); /* Mnemonic for "dead". */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#endif
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* The free list uses the "rounded-up" size "new_size": */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ((element *)mem)->next = ctx->freelists[new_size];
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->freelists[new_size] = (element *)mem;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * The stats[] uses the _actual_ "size" requested by the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * caller, with the caveat (in the code above) that "size" >= the
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * max. size (max_size) ends up getting recorded as a call to
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * max_size.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(ctx->stats[size].gets != 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->stats[size].gets--;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->stats[new_size].freefrags++;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid *
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater__isc_mem_getdebug(isc_mem_t *ctx, size_t size, const char *file, int line) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater void *ptr;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ptr = __isc_mem_get(ctx, size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(stderr, "%s:%d: mem_get(%p, %lu) -> %p\n", file, line,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx, (unsigned long)size, ptr);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ptr);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson
618a5e4923c3d064c1cc0f1866e27e8ddca90700Andreas Gustafssonvoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater__isc_mem_putdebug(isc_mem_t *ctx, void *ptr, size_t size, const char *file,
8f79820c6930ee5ef6b4a54f36d2559400bdf47dAndreas Gustafsson int line)
8f79820c6930ee5ef6b4a54f36d2559400bdf47dAndreas Gustafsson{
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson fprintf(stderr, "%s:%d: mem_put(%p, %p, %lu)\n", file, line,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence ctx, ptr, (unsigned long)size);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson __isc_mem_put(ctx, ptr, size);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson}
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson/*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Print the stats[] on the stream "out" with suitable formatting.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonvoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_stats(isc_mem_t *ctx, FILE *out)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff{
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t i;
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff const struct stats *s;
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff const isc_mempool_t *pool;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(VALID_CONTEXT(ctx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater LOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->freelists != NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater for (i = 1; i <= ctx->max_size; i++) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater s = &ctx->stats[i];
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (s->totalgets == 0 && s->gets == 0)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater continue;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(out, "%s%5d: %11lu gets, %11lu rem",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (i == ctx->max_size) ? ">=" : " ",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater i, s->totalgets, s->gets);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (s->blocks != 0)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(out, " (%lu bl, %lu ff)",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater s->blocks, s->freefrags);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fputc('\n', out);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Note that since a pool can be locked now, these stats might be
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * somewhat off if the pool is in active use at the time the stats
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * are dumped. The link fields are protected by the isc_mem_t's
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * lock, however, so walking this list and extracting integers from
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * stats fields is always safe.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater pool = ISC_LIST_HEAD(ctx->pools);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (pool != NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(out, "[Pool statistics]\n");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(out, "%15s %10s %10s %10s %10s %10s %10s %10s %1s\n",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "name", "size", "maxalloc", "allocated", "freecount",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater "freemax", "fillcount", "gets", "L");
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater while (pool != NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(out, "%15s %10u %10u %10u %10u %10u %10u %10u %s\n",
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater pool->name, pool->size, pool->maxalloc,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater pool->allocated, pool->freecount, pool->freemax,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater pool->fillcount, pool->gets,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (pool->lock == NULL ? "N" : "Y"));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater pool = ISC_LIST_NEXT(pool, link);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNLOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_boolean_t
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffisc_mem_valid(isc_mem_t *ctx, void *ptr) {
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff unsigned char *cp = ptr;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_boolean_t result = ISC_FALSE;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(VALID_CONTEXT(ctx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater LOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (ctx->lowest != NULL && cp >= ctx->lowest && cp <= ctx->highest)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater result = ISC_TRUE;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNLOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (result);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Replacements for malloc() and free().
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence */
7618f0551eb745354ee695907e568b0be1f2c8f5Andreas Gustafsson
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid *
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_allocate(isc_mem_t *ctx, size_t size) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_info *si;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size += ALIGNMENT_SIZE;
ce3c351d815569455892c30dc78d8c2e85ec1076Andreas Gustafsson si = isc_mem_get(ctx, size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (si == NULL)
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson return (NULL);
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson si->u.size = size;
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson return (&si[1]);
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson}
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafsson
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafssonvoid
a928d619170d61da40c3bff29800ff73709140daAndreas Gustafssonisc_mem_free(isc_mem_t *ctx, void *ptr) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_info *si;
03609d0b8f6e458d6bd4b460f4eb3f7270f487efDavid Lawrence
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater si = &(((size_info *)ptr)[-1]);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff isc_mem_put(ctx, si, si->u.size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
86a292d45977f1d8400df04b04bf659d9a5d68a1Andreas Gustafsson/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Other useful things.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrencechar *
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_strdup(isc_mem_t *mctx, const char *s) {
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson size_t len;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson char *ns;
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence len = strlen(s);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson ns = isc_mem_allocate(mctx, len + 1);
9b0e18da3d5c2290f90b285d122d368173f17c63Andreas Gustafsson if (ns == NULL)
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson return (NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater strncpy(ns, s, len + 1);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ns);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_boolean_t
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_destroy_check(isc_mem_t *mctx, isc_boolean_t flag) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_boolean_t oldval;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(mctx != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater oldval = mctx->checkfree;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mctx->checkfree = flag;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (oldval);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Quotas
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_setquota(isc_mem_t *ctx, size_t quota) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(VALID_CONTEXT(ctx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater LOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ctx->quota = quota;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNLOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatersize_t
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mem_getquota(isc_mem_t *ctx) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater size_t quota;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(VALID_CONTEXT(ctx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater LOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater quota = ctx->quota;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNLOCK(&ctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (quota);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#ifdef ISC_MEMCLUSTER_LEGACY
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson/*
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews * Public Legacy.
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstatic isc_mem_t *default_context = NULL;
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterint
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrencememinit(size_t init_max_size, size_t target_size) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* need default_context lock here */
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews if (default_context != NULL)
9a7d202077fae00fbdca610d8a8d90689e30f331Mark Andrews return (-1);
9a7d202077fae00fbdca610d8a8d90689e30f331Mark Andrews return (isc_mem_create(init_max_size, target_size, &default_context));
9a7d202077fae00fbdca610d8a8d90689e30f331Mark Andrews}
9a7d202077fae00fbdca610d8a8d90689e30f331Mark Andrews
9a7d202077fae00fbdca610d8a8d90689e30f331Mark Andrewsisc_mem_t *
ce3c351d815569455892c30dc78d8c2e85ec1076Andreas Gustafssonmem_default_context(void) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* need default_context lock here */
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews if (default_context == NULL && meminit(0, 0) == -1)
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews return (NULL);
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews return (default_context);
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid *
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater__memget(size_t size) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* need default_context lock here */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (default_context == NULL && meminit(0, 0) == -1)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (__mem_get(default_context, size));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater__memput(void *mem, size_t size) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* need default_context lock here */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(default_context != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater __mem_put(default_context, mem, size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid *
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater__memget_debug(size_t size, const char *file, int line) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater void *ptr;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ptr = __memget(size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(stderr, "%s:%d: memget(%lu) -> %p\n", file, line,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater (unsigned long)size, ptr);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ptr);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatervoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater__memput_debug(void *ptr, size_t size, const char *file, int line) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater fprintf(stderr, "%s:%d: memput(%p, %lu)\n", file, line,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ptr, (unsigned long)size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater __memput(ptr, size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterint
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrewsmemvalid(void *ptr) {
3a34b87c878990c6303358efd22265c2c5980c65Mark Andrews /* need default_context lock here */
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson REQUIRE(default_context != NULL);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson return (mem_valid(default_context, ptr));
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson}
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafssonvoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatermemstats(FILE *out) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /* need default_context lock here */
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff REQUIRE(default_context != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mem_stats(default_context, out);
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#endif /* ISC_MEMCLUSTER_LEGACY */
e44487bfc23599b6b240e09d83d1c862fecfcc82Michael Graff
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Memory pool stuff
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f991461dc144794d80ff8d85e430fd8a6e6113f3David Lawrence
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#if 0
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Free all but "n" items from the pool's free list. If n == 0, all items
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * will be returned to the mctx.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstatic void
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatermempool_release(isc_mempool_t *mpctx, unsigned int n)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater{
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mem_t *mctx;
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson element *item;
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff element *next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater unsigned int count;
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson mctx = mpctx->mctx;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (mpctx->freecount <= n)
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson return;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence INSIST(mpctx->items != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater item = mpctx->items;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater for (count = 0 ; count < n ; count++) {
ed04318ef686581fc9a20965a5be02abfb4f1bd5Andreas Gustafsson item = item->next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(item != NULL);
f951f076f3d321c52b824a866caff28ce4f8e06cAndreas Gustafsson }
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington /*
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington * All remaining items are to be freed. Lock the context once,
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * free them all, and unlock the context.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater LOCK(&mctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater do {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater next = item->next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mem_putunlocked(mctx, item, mpctx->size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(mpctx->freecount > 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx->freecount--;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater item = next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater } while (item != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNLOCK(&mctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#endif
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater/*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Release all items on the free list. No locking is done, the memory
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * context must be locked, and the pool if needed.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterstatic void
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updatermempool_releaseall(isc_mempool_t *mpctx)
c20ffa38dee7efa0dc01822d4bac5e41729b9b61Brian Wellington{
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews isc_mem_t *mctx;
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews element *item;
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews element *next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mctx = mpctx->mctx;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (mpctx->freecount == 0)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(mpctx->items != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater item = mpctx->items;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater do {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater next = item->next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mem_putunlocked(mctx, item, mpctx->size);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater INSIST(mpctx->freecount > 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx->freecount--;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater item = next;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater } while (item != NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_result_t
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater{
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater isc_mempool_t *mpctx;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(VALID_CONTEXT(mctx));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(size > 0);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater REQUIRE(mpctxp != NULL && *mpctxp == NULL);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater /*
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * Allocate space for this pool, initialize values, and if all works
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater * well, attach to the memory context.
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater */
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater LOCK(&mctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx = mem_getunlocked(mctx, sizeof(isc_mempool_t));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (mpctx == NULL) {
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNLOCK(&mctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ISC_R_NOMEMORY);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater }
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx->magic = MEMPOOL_MAGIC;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx->lock = NULL;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx->mctx = mctx;
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews mpctx->size = size;
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews mpctx->maxalloc = UINT_MAX;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx->allocated = 0;
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews mpctx->freecount = 0;
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews mpctx->freemax = 1;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx->fillcount = 1;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater mpctx->gets = 0;
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#if ISC_MEMPOOL_NAMES
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff mpctx->name[0] = 0;
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff#endif
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff mpctx->items = NULL;
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater *mpctxp = mpctx;
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater ISC_LIST_APPEND(mctx->pools, mpctx, link);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater UNLOCK(&mctx->lock);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater return (ISC_R_SUCCESS);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater}
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graffvoid
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updaterisc_mempool_setname(isc_mempool_t *mpctx, char *name)
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater{
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff REQUIRE(name != NULL);
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#if ISC_MEMPOOL_NAMES
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (mpctx->lock != NULL)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff LOCK(mpctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater memset(mpctx->name, 0, sizeof(mpctx->name));
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater strncpy(mpctx->name, name, sizeof(mpctx->name) - 1);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater if (mpctx->lock != NULL)
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff UNLOCK(mpctx->lock);
f172f06ff2e7609dd7d91914a44b4e24cff8bb7aAutomatic Updater#else
6c8abf481df85a67c3f32f5f107b554d3ff5a3edMark Andrews (void)mpctx;
b239c8294a5653d21876d084e0c5b029f6b9fc5dMichael Graff (void)name;
#endif
}
void
isc_mempool_destroy(isc_mempool_t **mpctxp)
{
isc_mempool_t *mpctx;
isc_mem_t *mctx;
isc_mutex_t *lock;
REQUIRE(mpctxp != NULL);
mpctx = *mpctxp;
REQUIRE(VALID_MEMPOOL(mpctx));
REQUIRE(mpctx->allocated == 0);
mctx = mpctx->mctx;
lock = mpctx->lock;
if (lock != NULL)
LOCK(lock);
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;
mem_putunlocked(mpctx->mctx, mpctx, sizeof(isc_mempool_t));
UNLOCK(&mctx->lock);
if (lock != NULL)
UNLOCK(lock);
*mpctxp = NULL;
}
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;
}
void *
__isc_mempool_get(isc_mempool_t *mpctx)
{
element *item;
isc_mem_t *mctx;
unsigned int i;
REQUIRE(VALID_MEMPOOL(mpctx));
mctx = mpctx->mctx;
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
/*
* Don't let the caller go over quota
*/
if (mpctx->allocated >= mpctx->maxalloc) {
item = NULL;
goto out;
}
/*
* 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++;
goto out;
}
/*
* 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++) {
item = mem_getunlocked(mctx, mpctx->size);
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)
goto out;
mpctx->items = item->next;
mpctx->freecount--;
mpctx->gets++;
mpctx->allocated++;
out:
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
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;
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
INSIST(mpctx->allocated > 0);
mpctx->allocated--;
/*
* If our free list is full, return this to the mctx directly.
*/
if (mpctx->freecount >= mpctx->freemax) {
__isc_mem_put(mctx, mem, mpctx->size);
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
return;
}
/*
* Otherwise, attach it to our free list and bump the counter.
*/
mpctx->freecount++;
item = (element *)mem;
item->next = mpctx->items;
mpctx->items = item;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
}
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));
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
mpctx->freemax = limit;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
}
unsigned int
isc_mempool_getfreemax(isc_mempool_t *mpctx)
{
unsigned int freemax;
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
freemax = mpctx->freemax;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
return (freemax);
}
unsigned int
isc_mempool_getfreecount(isc_mempool_t *mpctx)
{
unsigned int freecount;
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
freecount = mpctx->freecount;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
return (freecount);
}
void
isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit)
{
REQUIRE(limit > 0);
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
mpctx->maxalloc = limit;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
}
unsigned int
isc_mempool_getmaxalloc(isc_mempool_t *mpctx)
{
unsigned int maxalloc;
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
maxalloc = mpctx->maxalloc;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
return (maxalloc);
}
unsigned int
isc_mempool_getallocated(isc_mempool_t *mpctx)
{
unsigned int allocated;
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
allocated = mpctx->allocated;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
return (allocated);
}
void
isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit)
{
REQUIRE(limit > 0);
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
mpctx->fillcount = limit;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
}
unsigned int
isc_mempool_getfillcount(isc_mempool_t *mpctx)
{
unsigned int fillcount;
REQUIRE(VALID_MEMPOOL(mpctx));
if (mpctx->lock != NULL)
LOCK(mpctx->lock);
fillcount = mpctx->fillcount;
if (mpctx->lock != NULL)
UNLOCK(mpctx->lock);
return (fillcount);
}