diff options
author | kib <kib@FreeBSD.org> | 2017-07-14 07:42:57 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2017-07-14 07:42:57 +0000 |
commit | e754f74ed01ccc515d32e811a959ca896fd1abd7 (patch) | |
tree | b3f0e1de2bf0e00ab916a464046a53acaffcdf05 | |
parent | 493543cc05b3a1a0ce355c0d5e39219b5ca9f5fb (diff) | |
download | FreeBSD-src-e754f74ed01ccc515d32e811a959ca896fd1abd7.zip FreeBSD-src-e754f74ed01ccc515d32e811a959ca896fd1abd7.tar.gz |
MFC r320501:
Correct fences for sys/refcount.h.
-rw-r--r-- | sys/sys/refcount.h | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/sys/sys/refcount.h b/sys/sys/refcount.h index 4611664..7e6e977 100644 --- a/sys/sys/refcount.h +++ b/sys/sys/refcount.h @@ -50,7 +50,7 @@ refcount_acquire(volatile u_int *count) { KASSERT(*count < UINT_MAX, ("refcount %p overflowed", count)); - atomic_add_acq_int(count, 1); + atomic_add_int(count, 1); } static __inline int @@ -58,10 +58,20 @@ refcount_release(volatile u_int *count) { u_int old; - /* XXX: Should this have a rel membar? */ + atomic_thread_fence_rel(); old = atomic_fetchadd_int(count, -1); KASSERT(old > 0, ("negative refcount %p", count)); - return (old == 1); + if (old > 1) + return (0); + + /* + * Last reference. Signal the user to call the destructor. + * + * Ensure that the destructor sees all updates. The fence_rel + * at the start of the function synchronized with this fence. + */ + atomic_thread_fence_acq(); + return (1); } #endif /* ! __SYS_REFCOUNT_H__ */ |