diff options
author | rrs <rrs@FreeBSD.org> | 2007-01-15 15:06:28 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-01-15 15:06:28 +0000 |
commit | af870dbd2eb2b7c401adbdae5995f68a5ff112a3 (patch) | |
tree | 1a40f28088711881c0ca399c1f1df2b92b25259d /sys/kern/kern_subr.c | |
parent | bca9f253e79021e847dee8ce561a02c331094a0c (diff) | |
download | FreeBSD-src-af870dbd2eb2b7c401adbdae5995f68a5ff112a3.zip FreeBSD-src-af870dbd2eb2b7c401adbdae5995f68a5ff112a3.tar.gz |
Reviewed by: rwatson
Approved by: gnn
Add a new function hashinit_flags() which allows NOT-waiting
for memory (or waiting). The old hashinit() function now
calls hashinit_flags(..., HASH_WAITOK);
Diffstat (limited to 'sys/kern/kern_subr.c')
-rw-r--r-- | sys/kern/kern_subr.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c index ba288ac..cc19537 100644 --- a/sys/kern/kern_subr.c +++ b/sys/kern/kern_subr.c @@ -358,10 +358,11 @@ again: } /* - * General routine to allocate a hash table. + * General routine to allocate a hash table with control of memory flags. */ void * -hashinit(int elements, struct malloc_type *type, u_long *hashmask) +hashinit_flags(int elements, struct malloc_type *type, u_long *hashmask, + int flags) { long hashsize; LIST_HEAD(generic, generic) *hashtbl; @@ -369,16 +370,45 @@ hashinit(int elements, struct malloc_type *type, u_long *hashmask) if (elements <= 0) panic("hashinit: bad elements"); + + /* Check for valid flags. */ + KASSERT(flags | (HASH_WAITOK | HASH_NOWAIT) == + (HASH_WAITOK | HASH_NOWAIT), + ("Bad flags (0x%x) passed to hashinit_flags", flags)); + + /* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */ + KASSERT((flags & HASH_WAITOK) ^ (flags & HASH_NOWAIT), + ("Both WAITOK and NOWAIT passed to hashinit_flags")); + for (hashsize = 1; hashsize <= elements; hashsize <<= 1) continue; hashsize >>= 1; - hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK); - for (i = 0; i < hashsize; i++) - LIST_INIT(&hashtbl[i]); - *hashmask = hashsize - 1; + + if (flags & HASH_NOWAIT) + hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), + type, M_NOWAIT); + else + hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), + type, M_WAITOK); + + if (hashtbl != NULL) { + for (i = 0; i < hashsize; i++) + LIST_INIT(&hashtbl[i]); + *hashmask = hashsize - 1; + } return (hashtbl); } +/* + * Allocate and initialize a hash table with default flag: may sleep. + */ +void * +hashinit(int elements, struct malloc_type *type, u_long *hashmask) +{ + + return (hashinit_flags(elements, type, hashmask, HASH_WAITOK)); +} + void hashdestroy(void *vhashtbl, struct malloc_type *type, u_long hashmask) { |