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);
This commit is contained in:
rrs 2007-01-15 15:06:28 +00:00
parent bca9f253e7
commit af870dbd2e
4 changed files with 70 additions and 10 deletions

View File

@ -599,7 +599,8 @@ MLINKS+=hash.9 hash32.9 \
hash.9 hash32_strn.9 \
hash.9 hash32_strne.9
MLINKS+=hashinit.9 hashdestroy.9 \
hashinit.9 phashinit.9
hashinit.9 phashinit.9 \
hashinit.9 hashinit_flags.9
MLINKS+=ieee80211.9 ieee80211_attach.9 \
ieee80211.9 ieee80211_chan2ieee.9 \
ieee80211.9 ieee80211_chan2mode.9 \

View File

@ -29,7 +29,7 @@
.Dt HASHINIT 9
.Os
.Sh NAME
.Nm hashinit , hashdestroy , phashinit
.Nm hashinit , hashinit_flags, hashdestroy , phashinit
.Nd manage kernel hash tables
.Sh SYNOPSIS
.In sys/malloc.h
@ -38,12 +38,15 @@
.Ft "void *"
.Fn hashinit "int nelements" "struct malloc_type *type" "u_long *hashmask"
.Ft void
.Fn hashinit_flags "int nelements" "struct malloc_type *type" "u_long *hashmask" "int flags"
.Ft void
.Fn hashdestroy "void *hashtbl" "struct malloc_type *type" "u_long hashmask"
.Ft "void *"
.Fn phashinit "int nelements" "struct malloc_type *type" "u_long *nentries"
.Sh DESCRIPTION
The
.Fn hashinit
.Fn hashinit ,
.Fn hashinit_flags
and
.Fn phashinit
functions allocate space for hash tables of size given by the argument
@ -59,6 +62,13 @@ The
function allocates hash tables that are sized to the largest prime
number less than or equal to argument
.Fa nelements .
The
.Fn hashinit_flags
functionn operates like
.Fn hashinit
but also accepts an additional argument
.Fa flags
which control various options during allocation.
Allocated hash tables are contiguous arrays of
.Xr LIST_HEAD 3
entries, allocated using
@ -80,6 +90,20 @@ The argument
should be the bit mask returned by the call to
.Fn hashinit
that allocated the hash table.
The argument
.Fa flags
must be used with one of the following values.
.Pp
.Bl -tag -width ".Dv HASH_NOWAIT" -offset indent -compact
.It Dv HASH_NOWAIT
Any malloc performed by the
.Fn hashinit_flags
function will not be allowed to wait, and therefore may fail.
.It Dv HASH_WAITOK
Any malloc performed by the
.Fn hashinit_flags
function is allowed to wait for memory.
.El
.Sh IMPLEMENTATION NOTES
The largest prime hash value chosen by
.Fn phashinit

View File

@ -358,10 +358,11 @@ ureadc(int c, struct uio *uio)
}
/*
* 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)
{

View File

@ -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);