2 * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
26 #include <isc/random.h>
37 isc_pooldeallocator_t free;
38 isc_poolinitializer_t init;
48 alloc_pool(isc_mem_t *mctx, unsigned int count, isc_pool_t **poolp) {
51 pool = isc_mem_get(mctx, sizeof(*pool));
53 return (ISC_R_NOMEMORY);
59 isc_mem_attach(mctx, &pool->mctx);
60 pool->pool = isc_mem_get(mctx, count * sizeof(void *));
61 if (pool->pool == NULL) {
62 isc_mem_put(mctx, pool, sizeof(*pool));
63 return (ISC_R_NOMEMORY);
65 memset(pool->pool, 0, count * sizeof(void *));
68 return (ISC_R_SUCCESS);
72 isc_pool_create(isc_mem_t *mctx, unsigned int count,
73 isc_pooldeallocator_t free,
74 isc_poolinitializer_t init, void *initarg,
77 isc_pool_t *pool = NULL;
83 /* Allocate the pool structure */
84 result = alloc_pool(mctx, count, &pool);
85 if (result != ISC_R_SUCCESS)
90 pool->initarg = initarg;
92 /* Populate the pool */
93 for (i = 0; i < count; i++) {
94 result = init(&pool->pool[i], initarg);
95 if (result != ISC_R_SUCCESS) {
96 isc_pool_destroy(&pool);
102 return (ISC_R_SUCCESS);
106 isc_pool_get(isc_pool_t *pool) {
109 return (pool->pool[i % pool->count]);
113 isc_pool_count(isc_pool_t *pool) {
114 REQUIRE(pool != NULL);
115 return (pool->count);
119 isc_pool_expand(isc_pool_t **sourcep, unsigned int count,
120 isc_pool_t **targetp)
125 REQUIRE(sourcep != NULL && *sourcep != NULL);
126 REQUIRE(targetp != NULL && *targetp == NULL);
129 if (count > pool->count) {
130 isc_pool_t *newpool = NULL;
133 /* Allocate a new pool structure */
134 result = alloc_pool(pool->mctx, count, &newpool);
135 if (result != ISC_R_SUCCESS)
138 newpool->free = pool->free;
139 newpool->init = pool->init;
140 newpool->initarg = pool->initarg;
142 /* Copy over the objects from the old pool */
143 for (i = 0; i < pool->count; i++) {
144 newpool->pool[i] = pool->pool[i];
145 pool->pool[i] = NULL;
148 /* Populate the new entries */
149 for (i = pool->count; i < count; i++) {
150 result = pool->init(&newpool->pool[i], pool->initarg);
151 if (result != ISC_R_SUCCESS) {
152 isc_pool_destroy(&pool);
157 isc_pool_destroy(&pool);
163 return (ISC_R_SUCCESS);
167 isc_pool_destroy(isc_pool_t **poolp) {
169 isc_pool_t *pool = *poolp;
170 for (i = 0; i < pool->count; i++) {
171 if (pool->free != NULL && pool->pool[i] != NULL)
172 pool->free(&pool->pool[i]);
174 isc_mem_put(pool->mctx, pool->pool, pool->count * sizeof(void *));
175 isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));