1 /* $NetBSD: pool.c,v 1.1.1.3 2014/12/10 03:34:43 christos Exp $ */
4 * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
28 #include <isc/random.h>
39 isc_pooldeallocator_t free
;
40 isc_poolinitializer_t init
;
50 alloc_pool(isc_mem_t
*mctx
, unsigned int count
, isc_pool_t
**poolp
) {
53 pool
= isc_mem_get(mctx
, sizeof(*pool
));
55 return (ISC_R_NOMEMORY
);
61 isc_mem_attach(mctx
, &pool
->mctx
);
62 pool
->pool
= isc_mem_get(mctx
, count
* sizeof(void *));
63 if (pool
->pool
== NULL
) {
64 isc_mem_put(mctx
, pool
, sizeof(*pool
));
65 return (ISC_R_NOMEMORY
);
67 memset(pool
->pool
, 0, count
* sizeof(void *));
70 return (ISC_R_SUCCESS
);
74 isc_pool_create(isc_mem_t
*mctx
, unsigned int count
,
75 isc_pooldeallocator_t free
,
76 isc_poolinitializer_t init
, void *initarg
,
79 isc_pool_t
*pool
= NULL
;
85 /* Allocate the pool structure */
86 result
= alloc_pool(mctx
, count
, &pool
);
87 if (result
!= ISC_R_SUCCESS
)
92 pool
->initarg
= initarg
;
94 /* Populate the pool */
95 for (i
= 0; i
< count
; i
++) {
96 result
= init(&pool
->pool
[i
], initarg
);
97 if (result
!= ISC_R_SUCCESS
) {
98 isc_pool_destroy(&pool
);
104 return (ISC_R_SUCCESS
);
108 isc_pool_get(isc_pool_t
*pool
) {
111 return (pool
->pool
[i
% pool
->count
]);
115 isc_pool_count(isc_pool_t
*pool
) {
116 REQUIRE(pool
!= NULL
);
117 return (pool
->count
);
121 isc_pool_expand(isc_pool_t
**sourcep
, unsigned int count
,
122 isc_pool_t
**targetp
)
127 REQUIRE(sourcep
!= NULL
&& *sourcep
!= NULL
);
128 REQUIRE(targetp
!= NULL
&& *targetp
== NULL
);
131 if (count
> pool
->count
) {
132 isc_pool_t
*newpool
= NULL
;
135 /* Allocate a new pool structure */
136 result
= alloc_pool(pool
->mctx
, count
, &newpool
);
137 if (result
!= ISC_R_SUCCESS
)
140 newpool
->free
= pool
->free
;
141 newpool
->init
= pool
->init
;
142 newpool
->initarg
= pool
->initarg
;
144 /* Copy over the objects from the old pool */
145 for (i
= 0; i
< pool
->count
; i
++) {
146 newpool
->pool
[i
] = pool
->pool
[i
];
147 pool
->pool
[i
] = NULL
;
150 /* Populate the new entries */
151 for (i
= pool
->count
; i
< count
; i
++) {
152 result
= pool
->init(&newpool
->pool
[i
], pool
->initarg
);
153 if (result
!= ISC_R_SUCCESS
) {
154 isc_pool_destroy(&pool
);
159 isc_pool_destroy(&pool
);
165 return (ISC_R_SUCCESS
);
169 isc_pool_destroy(isc_pool_t
**poolp
) {
171 isc_pool_t
*pool
= *poolp
;
172 for (i
= 0; i
< pool
->count
; i
++) {
173 if (pool
->free
!= NULL
&& pool
->pool
[i
] != NULL
)
174 pool
->free(&pool
->pool
[i
]);
176 isc_mem_put(pool
->mctx
, pool
->pool
, pool
->count
* sizeof(void *));
177 isc_mem_putanddetach(&pool
->mctx
, pool
, sizeof(*pool
));