diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2016-05-18 03:46:04 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2016-05-18 03:46:04 +0000 |
commit | 73e2cbb8b2a34e42d0362509d4abd486264ac3c0 (patch) | |
tree | 5f74d9d3f6e0514b3564da375461cb32a1c9b3d7 /sys/kern/kern_srp.c | |
parent | 8a76118d0dc228d29251371c26cd0b91301ba059 (diff) |
rework the srp api so it takes an srp_ref struct that the caller provides.
the srp_ref struct is used to track the location of the callers
hazard pointer so later calls to srp_follow and srp_enter already
know what to clear. this in turn means most of the caveats around
using srps go away. specifically, you can now:
- switch cpus while holding an srp ref
- ie, you can sleep while holding an srp ref
- you can take and release srp refs in any order
the original intent was to simplify use of the api when dealing
with complicated data structures. the caller now no longer has to
track the location of the srp a value was fetched from, the srp_ref
effectively does that for you.
srp lists have been refactored to use srp_refs instead of srpl_iter
structs.
this is in preparation of using srps inside the ART code. ART is a
complicated data structure, and lookups require overlapping holds
of srp references.
ok mpi@ jmatthew@
Diffstat (limited to 'sys/kern/kern_srp.c')
-rw-r--r-- | sys/kern/kern_srp.c | 39 |
1 files changed, 9 insertions, 30 deletions
diff --git a/sys/kern/kern_srp.c b/sys/kern/kern_srp.c index 324e45bd3b3..4ae2c322898 100644 --- a/sys/kern/kern_srp.c +++ b/sys/kern/kern_srp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_srp.c,v 1.7 2015/11/23 10:56:19 mpi Exp $ */ +/* $OpenBSD: kern_srp.c,v 1.8 2016/05/18 03:46:03 dlg Exp $ */ /* * Copyright (c) 2014 Jonathan Matthew <jmatthew@openbsd.org> @@ -207,7 +207,7 @@ srp_v(struct srp_hazard *hzrd, struct srp *srp) } void * -srp_enter(struct srp *srp) +srp_enter(struct srp_ref *sr, struct srp *srp) { struct cpu_info *ci = curcpu(); struct srp_hazard *hzrd; @@ -215,8 +215,10 @@ srp_enter(struct srp *srp) for (i = 0; i < nitems(ci->ci_srp_hazards); i++) { hzrd = &ci->ci_srp_hazards[i]; - if (hzrd->sh_p == NULL) + if (hzrd->sh_p == NULL) { + sr->hz = hzrd; return (srp_v(hzrd, srp)); + } } panic("%s: not enough srp hazard records", __func__); @@ -226,38 +228,15 @@ srp_enter(struct srp *srp) } void * -srp_follow(struct srp *srp, void *v, struct srp *next) +srp_follow(struct srp_ref *sr, struct srp *srp) { - struct cpu_info *ci = curcpu(); - struct srp_hazard *hzrd; - - hzrd = ci->ci_srp_hazards + nitems(ci->ci_srp_hazards); - while (hzrd-- != ci->ci_srp_hazards) { - if (hzrd->sh_p == srp && hzrd->sh_v == v) - return (srp_v(hzrd, next)); - } - - panic("%s: unexpected ref %p via %p", __func__, v, srp); - - /* NOTREACHED */ - return (NULL); + return (srp_v(sr->hz, srp)); } void -srp_leave(struct srp *srp, void *v) +srp_leave(struct srp_ref *sr) { - struct cpu_info *ci = curcpu(); - struct srp_hazard *hzrd; - - hzrd = ci->ci_srp_hazards + nitems(ci->ci_srp_hazards); - while (hzrd-- != ci->ci_srp_hazards) { - if (hzrd->sh_p == srp && hzrd->sh_v == v) { - hzrd->sh_p = NULL; - return; - } - } - - panic("%s: unexpected ref %p via %p", __func__, v, srp); + sr->hz->sh_p = NULL; } #else /* MULTIPROCESSOR */ |