Annotation of src/sys/kern/subr_pool.c, Revision 1.2
1.2 ! pk 1: /* $NetBSD: subr_pool.c,v 1.1 1997/12/15 11:14:57 pk Exp $ */
1.1 pk 2:
3: /*-
4: * Copyright (c) 1997 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Paul Kranenburg.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the NetBSD
21: * Foundation, Inc. and its contributors.
22: * 4. Neither the name of The NetBSD Foundation nor the names of its
23: * contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
38:
39: #include <sys/param.h>
40: #include <sys/systm.h>
41: #include <sys/proc.h>
42: #include <sys/errno.h>
43: #include <sys/kernel.h>
44: #include <sys/malloc.h>
45: #include <sys/lock.h>
46: #include <sys/pool.h>
47:
48: /*
49: * Pool resource management utility.
50: */
51:
52: struct pool_item {
53: struct pool_item *pi_next;
54: };
55:
56:
57: struct pool *
1.2 ! pk 58: pool_create(size, nitems, wchan, mtype, storage)
1.1 pk 59: size_t size;
60: int nitems;
61: char *wchan;
62: int mtype;
1.2 ! pk 63: caddr_t storage;
1.1 pk 64: {
65: struct pool *pp;
1.2 ! pk 66: caddr_t cp;
1.1 pk 67:
68: if (size < sizeof(struct pool_item)) {
69: printf("pool_create: size %lu too small\n", (u_long)size);
70: return (NULL);
71: }
72:
1.2 ! pk 73: if (storage) {
! 74: pp = (struct pool *)storage;
! 75: cp = (caddr_t)ALIGN(pp + 1);
! 76: } else {
! 77: pp = (struct pool *)malloc(sizeof(*pp), mtype, M_NOWAIT);
! 78: if (pp == NULL)
! 79: return (NULL);
! 80: cp = NULL;
! 81: }
1.1 pk 82:
83: pp->pr_freelist = NULL;
84: pp->pr_freecount = 0;
85: pp->pr_hiwat = 0;
1.2 ! pk 86: pp->pr_flags = (storage ? PR_STATIC : 0);
1.1 pk 87: pp->pr_size = size;
88: pp->pr_wchan = wchan;
89: pp->pr_mtype = mtype;
90: simple_lock_init(&pp->pr_lock);
91:
92: if (nitems != 0) {
1.2 ! pk 93: if (pool_prime(pp, nitems, cp) != 0) {
1.1 pk 94: pool_destroy(pp);
1.2 ! pk 95: return (NULL);
! 96: }
1.1 pk 97: }
98:
99: return (pp);
100: }
101:
102: /*
103: * De-commision a pool resource.
104: */
105: void
106: pool_destroy(pp)
107: struct pool *pp;
108: {
109: struct pool_item *pi;
110:
1.2 ! pk 111: if (pp->pr_flags & PR_STATIC)
! 112: return;
! 113:
1.1 pk 114: while ((pi = pp->pr_freelist) != NULL) {
115: pp->pr_freelist = pi->pi_next;
116: free(pi, pp->pr_mtype);
117: }
118: free(pp, pp->pr_mtype);
119: }
120:
121:
122: /*
123: * Grab an item from the pool; must be called at splbio
124: */
125: void *
126: pool_get(pp, flags)
127: struct pool *pp;
128: int flags;
129: {
130: void *v;
131: struct pool_item *pi;
132:
1.2 ! pk 133: #ifdef DIAGNOSTIC
! 134: if ((pp->pr_flags & PR_STATIC) && (flags & PR_MALLOCOK))
! 135: panic("pool_get: static");
! 136: #endif
! 137:
1.1 pk 138: again:
139: simple_lock(&pp->pr_lock);
140: if ((v = pp->pr_freelist) == NULL) {
141: if (flags & PR_MALLOCOK)
142: v = (void *)malloc(pp->pr_size, pp->pr_mtype, M_NOWAIT);
143:
144: if (v == NULL) {
145: if ((flags & PR_WAITOK) == 0)
146: return (NULL);
147: pp->pr_flags |= PR_WANTED;
148: simple_unlock(&pp->pr_lock);
149: tsleep((caddr_t)pp, PSWP, pp->pr_wchan, 0);
150: goto again;
151: }
152: } else {
153: pi = v;
154: pp->pr_freelist = pi->pi_next;
155: pp->pr_freecount--;
156: }
157: simple_unlock(&pp->pr_lock);
158: return (v);
159: }
160:
161: /*
162: * Return resource to the pool; must be called at splbio
163: */
164: void
165: pool_put(pp, v)
166: struct pool *pp;
167: void *v;
168: {
169: struct pool_item *pi = v;
170:
171: simple_lock(&pp->pr_lock);
172: if ((pp->pr_flags & PR_WANTED) || pp->pr_freecount < pp->pr_hiwat) {
173: /* Return to pool */
174: pi->pi_next = pp->pr_freelist;
175: pp->pr_freelist = pi;
176: pp->pr_freecount++;
177: if (pp->pr_flags & PR_WANTED) {
178: pp->pr_flags &= ~PR_WANTED;
179: wakeup((caddr_t)pp);
180: }
181: } else {
1.2 ! pk 182: #ifdef DIAGNOSTIC
! 183: if (pp->pr_flags & PR_STATIC) {
! 184: /* can't happen because hiwat > freecount */
! 185: panic("pool_put: static");
! 186: }
! 187: #endif
1.1 pk 188: /* Return to system */
189: free(v, M_DEVBUF);
190:
191: /*
192: * Return any excess items allocated during periods of
193: * contention.
194: */
195: while (pp->pr_freecount > pp->pr_hiwat) {
196: pi = pp->pr_freelist;
197: pp->pr_freelist = pi->pi_next;
198: pp->pr_freecount--;
199: free(pi, M_DEVBUF);
200: }
201: }
202: simple_unlock(&pp->pr_lock);
203: }
204:
205: /*
206: * Add N items to the pool
207: */
208: int
1.2 ! pk 209: pool_prime(pp, n, storage)
1.1 pk 210: struct pool *pp;
211: int n;
1.2 ! pk 212: caddr_t storage;
1.1 pk 213: {
214: struct pool_item *pi;
1.2 ! pk 215: caddr_t cp = storage;
! 216:
! 217: #ifdef DIAGNOSTIC
! 218: if (storage && !(pp->pr_flags & PR_STATIC))
! 219: panic("pool_prime: static");
! 220: /* !storage && static caught below */
! 221: #endif
1.1 pk 222:
223: simple_lock(&pp->pr_lock);
224: pp->pr_hiwat += n;
225: while (n--) {
1.2 ! pk 226: if (pp->pr_flags & PR_STATIC) {
! 227: pi = (struct pool_item *)cp;
! 228: cp = (caddr_t)ALIGN(cp + pp->pr_size);
! 229: } else
! 230: pi = malloc(pp->pr_size, pp->pr_mtype, M_NOWAIT);
! 231:
1.1 pk 232: if (pi == NULL) {
233: simple_unlock(&pp->pr_lock);
234: return (ENOMEM);
235: }
236:
237: pi->pi_next = pp->pr_freelist;
238: pp->pr_freelist = pi;
239: pp->pr_freecount++;
240: }
241: simple_unlock(&pp->pr_lock);
242: return (0);
243: }
CVSweb <webmaster@jp.NetBSD.org>