128993443SEd Schouten /*- 228993443SEd Schouten * Copyright (c) 1982, 1986, 1991, 1993 328993443SEd Schouten * The Regents of the University of California. All rights reserved. 428993443SEd Schouten * (c) UNIX System Laboratories, Inc. 528993443SEd Schouten * All or some portions of this file are derived from material licensed 628993443SEd Schouten * to the University of California by American Telephone and Telegraph 728993443SEd Schouten * Co. or Unix System Laboratories, Inc. and are reproduced herein with 828993443SEd Schouten * the permission of UNIX System Laboratories, Inc. 928993443SEd Schouten * 1028993443SEd Schouten * Redistribution and use in source and binary forms, with or without 1128993443SEd Schouten * modification, are permitted provided that the following conditions 1228993443SEd Schouten * are met: 1328993443SEd Schouten * 1. Redistributions of source code must retain the above copyright 1428993443SEd Schouten * notice, this list of conditions and the following disclaimer. 1528993443SEd Schouten * 2. Redistributions in binary form must reproduce the above copyright 1628993443SEd Schouten * notice, this list of conditions and the following disclaimer in the 1728993443SEd Schouten * documentation and/or other materials provided with the distribution. 1828993443SEd Schouten * 4. Neither the name of the University nor the names of its contributors 1928993443SEd Schouten * may be used to endorse or promote products derived from this software 2028993443SEd Schouten * without specific prior written permission. 2128993443SEd Schouten * 2228993443SEd Schouten * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2328993443SEd Schouten * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2428993443SEd Schouten * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2528993443SEd Schouten * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2628993443SEd Schouten * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2728993443SEd Schouten * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2828993443SEd Schouten * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2928993443SEd Schouten * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3028993443SEd Schouten * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3128993443SEd Schouten * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3228993443SEd Schouten * SUCH DAMAGE. 3328993443SEd Schouten * 3428993443SEd Schouten * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94 3528993443SEd Schouten */ 3628993443SEd Schouten 3728993443SEd Schouten #include <sys/cdefs.h> 3828993443SEd Schouten __FBSDID("$FreeBSD$"); 3928993443SEd Schouten 4028993443SEd Schouten #include <sys/param.h> 4128993443SEd Schouten #include <sys/systm.h> 4228993443SEd Schouten #include <sys/malloc.h> 4328993443SEd Schouten 4428993443SEd Schouten /* 4528993443SEd Schouten * General routine to allocate a hash table with control of memory flags. 4628993443SEd Schouten */ 4728993443SEd Schouten void * 4828993443SEd Schouten hashinit_flags(int elements, struct malloc_type *type, u_long *hashmask, 4928993443SEd Schouten int flags) 5028993443SEd Schouten { 5128993443SEd Schouten long hashsize; 5228993443SEd Schouten LIST_HEAD(generic, generic) *hashtbl; 5328993443SEd Schouten int i; 5428993443SEd Schouten 5593a1b4c4SGleb Smirnoff KASSERT(elements > 0, ("%s: bad elements", __func__)); 5628993443SEd Schouten /* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */ 5728993443SEd Schouten KASSERT((flags & HASH_WAITOK) ^ (flags & HASH_NOWAIT), 5828993443SEd Schouten ("Bad flags (0x%x) passed to hashinit_flags", flags)); 5928993443SEd Schouten 6028993443SEd Schouten for (hashsize = 1; hashsize <= elements; hashsize <<= 1) 6128993443SEd Schouten continue; 6228993443SEd Schouten hashsize >>= 1; 6328993443SEd Schouten 6428993443SEd Schouten if (flags & HASH_NOWAIT) 6528993443SEd Schouten hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), 6628993443SEd Schouten type, M_NOWAIT); 6728993443SEd Schouten else 6828993443SEd Schouten hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), 6928993443SEd Schouten type, M_WAITOK); 7028993443SEd Schouten 7128993443SEd Schouten if (hashtbl != NULL) { 7228993443SEd Schouten for (i = 0; i < hashsize; i++) 7328993443SEd Schouten LIST_INIT(&hashtbl[i]); 7428993443SEd Schouten *hashmask = hashsize - 1; 7528993443SEd Schouten } 7628993443SEd Schouten return (hashtbl); 7728993443SEd Schouten } 7828993443SEd Schouten 7928993443SEd Schouten /* 8028993443SEd Schouten * Allocate and initialize a hash table with default flag: may sleep. 8128993443SEd Schouten */ 8228993443SEd Schouten void * 8328993443SEd Schouten hashinit(int elements, struct malloc_type *type, u_long *hashmask) 8428993443SEd Schouten { 8528993443SEd Schouten 8628993443SEd Schouten return (hashinit_flags(elements, type, hashmask, HASH_WAITOK)); 8728993443SEd Schouten } 8828993443SEd Schouten 8928993443SEd Schouten void 9028993443SEd Schouten hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask) 9128993443SEd Schouten { 9228993443SEd Schouten LIST_HEAD(generic, generic) *hashtbl, *hp; 9328993443SEd Schouten 9428993443SEd Schouten hashtbl = vhashtbl; 9528993443SEd Schouten for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++) 96029f99dcSBjoern A. Zeeb KASSERT(LIST_EMPTY(hp), ("%s: hashtbl %p not empty " 97029f99dcSBjoern A. Zeeb "(malloc type %s)", __func__, hashtbl, type->ks_shortdesc)); 9828993443SEd Schouten free(hashtbl, type); 9928993443SEd Schouten } 10028993443SEd Schouten 10128993443SEd Schouten static const int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531, 10228993443SEd Schouten 2039, 2557, 3067, 3583, 4093, 4603, 5119, 5623, 6143, 10328993443SEd Schouten 6653, 7159, 7673, 8191, 12281, 16381, 24571, 32749 }; 104*02abd400SPedro F. Giffuni #define NPRIMES nitems(primes) 10528993443SEd Schouten 10628993443SEd Schouten /* 10728993443SEd Schouten * General routine to allocate a prime number sized hash table. 10828993443SEd Schouten */ 10928993443SEd Schouten void * 11028993443SEd Schouten phashinit(int elements, struct malloc_type *type, u_long *nentries) 11128993443SEd Schouten { 11228993443SEd Schouten long hashsize; 11328993443SEd Schouten LIST_HEAD(generic, generic) *hashtbl; 11428993443SEd Schouten int i; 11528993443SEd Schouten 11693a1b4c4SGleb Smirnoff KASSERT(elements > 0, ("%s: bad elements", __func__)); 11728993443SEd Schouten for (i = 1, hashsize = primes[1]; hashsize <= elements;) { 11828993443SEd Schouten i++; 11928993443SEd Schouten if (i == NPRIMES) 12028993443SEd Schouten break; 12128993443SEd Schouten hashsize = primes[i]; 12228993443SEd Schouten } 12328993443SEd Schouten hashsize = primes[i - 1]; 12428993443SEd Schouten hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK); 12528993443SEd Schouten for (i = 0; i < hashsize; i++) 12628993443SEd Schouten LIST_INIT(&hashtbl[i]); 12728993443SEd Schouten *nentries = hashsize; 12828993443SEd Schouten return (hashtbl); 12928993443SEd Schouten } 130