On Thu, Mar 10, 2022 at 02:03:26PM +0000, Visa Hankala wrote: > My understanding is that OpenBSD's atomic_* instructions are relaxed > in terms of memory order. To accomplish a specific form of semantics, > the user adds the appropriate memory barrier instruction. Well, this > is the plan at least, I think.
I also think that. > Below is a patch that shows how to accomplish release semantics with > the file and refcnt APIs. (The added memory barriers ensure that the > CPU completes its loads and stores to the object before dropping the > reference. Another CPU might delete the object immediately after. > The barrier might not be strictly necessary with refcnt_finalize(), > though.) OK bluhm@ > Index: kern/kern_synch.c > =================================================================== > RCS file: src/sys/kern/kern_synch.c,v > retrieving revision 1.182 > diff -u -p -r1.182 kern_synch.c > --- kern/kern_synch.c 19 Feb 2022 23:56:18 -0000 1.182 > +++ kern/kern_synch.c 10 Mar 2022 13:37:50 -0000 > @@ -825,6 +825,7 @@ refcnt_rele(struct refcnt *r) > { > u_int refcnt; > > + membar_exit_before_atomic(); > refcnt = atomic_dec_int_nv(&r->refs); > KASSERT(refcnt != ~0); > > @@ -844,6 +845,7 @@ refcnt_finalize(struct refcnt *r, const > struct sleep_state sls; > u_int refcnt; > > + membar_exit_before_atomic(); > refcnt = atomic_dec_int_nv(&r->refs); > while (refcnt) { > sleep_setup(&sls, r, PWAIT, wmesg, 0); > Index: sys/file.h > =================================================================== > RCS file: src/sys/sys/file.h,v > retrieving revision 1.65 > diff -u -p -r1.65 file.h > --- sys/file.h 20 Jan 2022 03:43:31 -0000 1.65 > +++ sys/file.h 10 Mar 2022 13:37:50 -0000 > @@ -36,6 +36,7 @@ > #include <sys/fcntl.h> > > #else /* _KERNEL */ > +#include <sys/atomic.h> > #include <sys/queue.h> > #include <sys/mutex.h> > #endif /* _KERNEL */ > @@ -113,13 +114,21 @@ struct file { > atomic_inc_int(&(fp)->f_count); \ > } while (0) > > -#define FRELE(fp,p) \ > - (atomic_dec_int_nv(&fp->f_count) == 0 ? fdrop(fp, p) : 0) > - > #define FDUP_MAX_COUNT (UINT_MAX - 2 * MAXCPUS) > > int fdrop(struct file *, struct proc *); > > +static inline int > +FRELE(struct file *fp, struct proc *p) > +{ > + int error = 0; > + > + membar_exit_before_atomic(); > + if (atomic_dec_int_nv(&fp->f_count) == 0) > + error = fdrop(fp, p); > + return (error); > +} > + > static inline off_t > foffset(struct file *fp) > {