diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_subr.c | 42 | ||||
-rw-r--r-- | sys/sys/systm.h | 7 |
2 files changed, 42 insertions, 7 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) { diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 96b937d..e84bf1b 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -134,7 +134,12 @@ int nullop(void); int eopnotsupp(void); int ureadc(int, struct uio *); void hashdestroy(void *, struct malloc_type *, u_long); -void *hashinit(int count, struct malloc_type *type, u_long *hashmask); +void *hashinit(int count, struct malloc_type *type, u_long *hashmark); +void *hashinit_flags(int count, struct malloc_type *type, + u_long *hashmask, int flags); +#define HASH_NOWAIT 0x00000001 +#define HASH_WAITOK 0x00000002 + void *phashinit(int count, struct malloc_type *type, u_long *nentries); void g_waitidle(void); |