Page MenuHomeFreeBSD

hash(9): introduce hashalloc()/hashfree() KPI
AcceptedPublic

Authored by glebius on Tue, Mar 17, 7:27 PM.
Tags
None
Referenced Files
F148939246: D55904.id173831.diff
Sat, Mar 21, 4:27 AM
F148894112: D55904.diff
Fri, Mar 20, 8:15 PM
Unknown Object (File)
Fri, Mar 20, 3:55 AM

Details

Reviewers
gallatin
pouria
Group Reviewers
Src Committers
Doc Committers
Summary

This is a more extendable version than traditional hashinit(9). It allows
different kinds of slot headers with optional locks.

Implement traditional hashinit()/hashdestroy() on top of it.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 71468
Build 68351: arc lint + arc unit

Event Timeline

Last minute change before sharing of course had a small mistake :)

This is really clever. What about other lock types (rm / rms, sx, etc)?

I'll see if rmlock(9) and sx(9) can be added and update.

Do you need to validate the enum value is know?

Can the lock and list types be automatically detected with _Generic somehow?

In D55904#1279057, @imp wrote:

Do you need to validate the enum value is know?

Do you mean if somebody passes a numeric instead of one of enum values? I think our compiler flags will forbid that.

Can the lock and list types be automatically detected with _Generic somehow?

I don't see a way to use _Generic facing outside of the KPI. It might be possible to make some use of it internally, I'll look into that.

Add sx(9) and rmlock(9) support.

In D55904#1279057, @imp wrote:

Do you need to validate the enum value is know?

Do you mean if somebody passes a numeric instead of one of enum values? I think our compiler flags will forbid that.

I'm thinking default: would make sure.

Can the lock and list types be automatically detected with _Generic somehow?

I don't see a way to use _Generic facing outside of the KPI. It might be possible to make some use of it internally, I'll look into that.

Sure.

Some additions to the manual page.

This revision is now accepted and ready to land.Wed, Mar 18, 5:28 PM
sys/kern/subr_hash.c
160–162

Why <= then >>=?
why not just <?

share/man/man9/hashinit.9
47–52

Are we going to remove hashinit_flags and hashdestroy as well?
We just updated them to use the new KPI, and we inform users that we plan to obsolete them at the same time.
If that's not the case, IMHO, we should include them in the new manual.
Otherwise, we should put a deprecation warning above their functions.

sys/kern/subr_hash.c
180

style?

284

style?

share/man/man9/hashalloc.9
2–3

SPDX tag?

jhb added inline comments.
share/man/man9/hashalloc.9
59

Usually contiguous means "physically contiguous" in the kernel (e.g. contigmalloc). malloc() always returns virtually contiguous memory, so if you are only talking about virtual contiguous here, I would remove the word to avoid confusion.

sys/kern/subr_hash.c
180

If you make slot and men of type char * instead of void * you can avoid all the char * casts. char * is the pointer spelling of uintptr_t as it were.

272

Can args be const here? That would clarify that hashfree can't return an error.

sys/kern/subr_hash.c
160–162

This follows exactly logic of hashinit(9):

The hashinit() function allocates hash tables that are sized to largest power of two less than or equal to argument nelements.

And new API offers the same wording. With suggested code we would create a power of two that is greater or equal.

From the hashinit(9) it is not actually clear what they meant with nelements - hash slots or objects stored in the hash? Most modern code treats as the former. But it could be that original logic was that nelements is expected number of objects. In that case logic makes sense, as we don't want guaranteed underfilled hashes. For example, nelements = 5 shall yield in size 4 hash not in size 8.

180

Pouria, I strongly disagreed with the part of style(9) that suggest to put all variable declarations to the top of the function. And if I remember correct this demand from the style.7 was finally removed.

I find a code much easier to read when variables are limited in their visibility scope. This also sends a hint to any future editor of the code, that the variable is supposed to have a limited visibility for a reason.

180

John, this can be done for hashalloc() easily and for hashfree() we would need an extra local variable to recast the argument from void *. I can do it if you insist.

But, IMHO, if I give you three code snippets without any extra context, and you need to guess the types and guess what the coder wanted to achieve:

header = header + i * hdrsize;
slot = (char *)mem + i * hdrsize;
slot = mem + i * hdrsize;

, then in the first two cases the result will be obvious to you and in the very last case it will be not. What I'm trying to tell is that (char *)s here are improving readability :) But if you insist, I can do that.

272

Right now hashfree() may change args->hdrsize, as it calls hashalloc_sizes(). With extra coding this can be avoided, of course.

I do not see a value to put const into API here. The structure is supposed to be opaque to the caller and is not supposed to be used with anything else except this API. Not to be shares with anything else. What value would constness give?

LGTM
Phabricator won't let me accept behalf of myself.