[BACK]Return to subr_pool.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

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>