1 /* $OpenBSD: pool.h,v 1.24 2007/05/28 17:55:56 tedu Exp $ */
2 /* $NetBSD: pool.h,v 1.27 2001/06/06 22:00:17 rafal Exp $ */
3
4 /*-
5 * Copyright (c) 1997, 1998, 1999, 2000 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Paul Kranenburg; by Jason R. Thorpe of the Numerical Aerospace
10 * Simulation Facility, NASA Ames Research Center.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 #ifndef _SYS_POOL_H_
42 #define _SYS_POOL_H_
43
44 /*
45 * sysctls.
46 * kern.pool.npools
47 * kern.pool.name.<number>
48 * kern.pool.pool.<number>
49 */
50 #define KERN_POOL_NPOOLS 1
51 #define KERN_POOL_NAME 2
52 #define KERN_POOL_POOL 3
53
54 #include <sys/lock.h>
55 #include <sys/queue.h>
56 #include <sys/time.h>
57 #include <sys/tree.h>
58
59 struct pool_cache {
60 TAILQ_ENTRY(pool_cache)
61 pc_poollist; /* entry on pool's group list */
62 TAILQ_HEAD(, pool_cache_group)
63 pc_grouplist; /* Cache group list */
64 struct pool_cache_group
65 *pc_allocfrom; /* group to allocate from */
66 struct pool_cache_group
67 *pc_freeto; /* group to free to */
68 struct pool *pc_pool; /* parent pool */
69 struct simplelock pc_slock; /* mutex */
70
71 int (*pc_ctor)(void *, void *, int);
72 void (*pc_dtor)(void *, void *);
73 void *pc_arg;
74
75 /* Statistics. */
76 unsigned long pc_hits; /* cache hits */
77 unsigned long pc_misses; /* cache misses */
78
79 unsigned long pc_ngroups; /* # cache groups */
80
81 unsigned long pc_nitems; /* # objects currently in cache */
82 };
83
84 struct pool_allocator {
85 void *(*pa_alloc)(struct pool *, int);
86 void (*pa_free)(struct pool *, void *);
87 int pa_pagesz;
88
89 /* The following fields are for internal use only */
90 struct simplelock pa_slock;
91 TAILQ_HEAD(,pool) pa_list;
92 int pa_flags;
93 #define PA_INITIALIZED 0x01
94 #define PA_WANT 0x02 /* wakeup any sleeping pools on free */
95 int pa_pagemask;
96 int pa_pageshift;
97 };
98
99 LIST_HEAD(pool_pagelist,pool_item_header);
100
101 struct pool {
102 TAILQ_ENTRY(pool)
103 pr_poollist;
104 struct pool_pagelist
105 pr_emptypages; /* Empty pages */
106 struct pool_pagelist
107 pr_fullpages; /* Full pages */
108 struct pool_pagelist
109 pr_partpages; /* Partially-allocated pages */
110 struct pool_item_header *pr_curpage;
111 TAILQ_HEAD(,pool_cache)
112 pr_cachelist; /* Caches for this pool */
113 unsigned int pr_size; /* Size of item */
114 unsigned int pr_align; /* Requested alignment, must be 2^n */
115 unsigned int pr_itemoffset; /* Align this offset in item */
116 unsigned int pr_minitems; /* minimum # of items to keep */
117 unsigned int pr_minpages; /* same in page units */
118 unsigned int pr_maxpages; /* maximum # of idle pages to keep */
119 unsigned int pr_npages; /* # of pages allocated */
120 unsigned int pr_itemsperpage;/* # items that fit in a page */
121 unsigned int pr_slack; /* unused space in a page */
122 unsigned int pr_nitems; /* number of available items in pool */
123 unsigned int pr_nout; /* # items currently allocated */
124 unsigned int pr_hardlimit; /* hard limit to number of allocated
125 items */
126 unsigned int pr_serial; /* unique serial number of the pool */
127 struct pool_allocator *pr_alloc;/* backend allocator */
128 TAILQ_ENTRY(pool) pr_alloc_list;/* list of pools using this allocator */
129 const char *pr_wchan; /* tsleep(9) identifier */
130 unsigned int pr_flags; /* r/w flags */
131 unsigned int pr_roflags; /* r/o flags */
132 #define PR_MALLOCOK 0x01
133 #define PR_NOWAIT 0x00 /* for symmetry */
134 #define PR_WAITOK 0x02
135 #define PR_WANTED 0x04
136 #define PR_PHINPAGE 0x08
137 #define PR_LOGGING 0x10
138 #define PR_LIMITFAIL 0x20 /* even if waiting, fail if we hit limit */
139 #define PR_DEBUG 0x40
140
141 /*
142 * `pr_slock' protects the pool's data structures when removing
143 * items from or returning items to the pool, or when reading
144 * or updating read/write fields in the pool descriptor.
145 *
146 * We assume back-end page allocators provide their own locking
147 * scheme. They will be called with the pool descriptor _unlocked_,
148 * since the page allocators may block.
149 */
150 struct simplelock pr_slock;
151 int pr_ipl;
152
153 SPLAY_HEAD(phtree, pool_item_header) pr_phtree;
154
155 int pr_maxcolor; /* Cache colouring */
156 int pr_curcolor;
157 int pr_phoffset; /* Offset in page of page header */
158
159 /*
160 * Warning message to be issued, and a per-time-delta rate cap,
161 * if the hard limit is reached.
162 */
163 const char *pr_hardlimit_warning;
164 struct timeval pr_hardlimit_ratecap;
165 struct timeval pr_hardlimit_warning_last;
166
167 /*
168 * Instrumentation
169 */
170 unsigned long pr_nget; /* # of successful requests */
171 unsigned long pr_nfail; /* # of unsuccessful requests */
172 unsigned long pr_nput; /* # of releases */
173 unsigned long pr_npagealloc; /* # of pages allocated */
174 unsigned long pr_npagefree; /* # of pages released */
175 unsigned int pr_hiwat; /* max # of pages in pool */
176 unsigned long pr_nidle; /* # of idle pages */
177
178 /*
179 * Diagnostic aides.
180 */
181 struct pool_log *pr_log;
182 int pr_curlogentry;
183 int pr_logsize;
184
185 const char *pr_entered_file; /* reentrancy check */
186 long pr_entered_line;
187 };
188
189 #ifdef _KERNEL
190 /* old nointr allocator, still needed for large allocations */
191 extern struct pool_allocator pool_allocator_oldnointr;
192
193 extern struct pool_allocator pool_allocator_nointr;
194
195 void pool_init(struct pool *, size_t, u_int, u_int, int,
196 const char *, struct pool_allocator *);
197 #ifdef DIAGNOSTIC
198 void pool_setipl(struct pool *, int);
199 #else
200 #define pool_setipl(p, i) do { /* nothing */ } while (0)
201 #endif
202 void pool_destroy(struct pool *);
203
204 void *pool_get(struct pool *, int) __malloc;
205 void pool_put(struct pool *, void *);
206 int pool_reclaim(struct pool *);
207
208 #ifdef POOL_DIAGNOSTIC
209 /*
210 * These versions do reentrancy checking.
211 */
212 void *_pool_get(struct pool *, int, const char *, long);
213 void _pool_put(struct pool *, void *, const char *, long);
214 int _pool_reclaim(struct pool *, const char *, long);
215 #define pool_get(h, f) _pool_get((h), (f), __FILE__, __LINE__)
216 #define pool_put(h, v) _pool_put((h), (v), __FILE__, __LINE__)
217 #define pool_reclaim(h) _pool_reclaim((h), __FILE__, __LINE__)
218 #endif /* POOL_DIAGNOSTIC */
219
220 int pool_prime(struct pool *, int);
221 void pool_setlowat(struct pool *, int);
222 void pool_sethiwat(struct pool *, int);
223 int pool_sethardlimit(struct pool *, unsigned, const char *, int);
224
225 #ifdef DDB
226 /*
227 * Debugging and diagnostic aides.
228 */
229 void pool_printit(struct pool *, const char *,
230 int (*)(const char *, ...));
231 int pool_chk(struct pool *, const char *);
232 #endif
233
234 /*
235 * Pool cache routines.
236 */
237 void pool_cache_init(struct pool_cache *, struct pool *,
238 int (*ctor)(void *, void *, int),
239 void (*dtor)(void *, void *),
240 void *);
241 void pool_cache_destroy(struct pool_cache *);
242 void *pool_cache_get(struct pool_cache *, int);
243 void pool_cache_put(struct pool_cache *, void *);
244 void pool_cache_destruct_object(struct pool_cache *, void *);
245 void pool_cache_invalidate(struct pool_cache *);
246 #endif /* _KERNEL */
247
248 #endif /* _SYS_POOL_H_ */