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:
parent
bca9f253e7
commit
af870dbd2e
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user