summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2017-07-14 07:42:57 +0000
committerkib <kib@FreeBSD.org>2017-07-14 07:42:57 +0000
commite754f74ed01ccc515d32e811a959ca896fd1abd7 (patch)
treeb3f0e1de2bf0e00ab916a464046a53acaffcdf05
parent493543cc05b3a1a0ce355c0d5e39219b5ca9f5fb (diff)
downloadFreeBSD-src-e754f74ed01ccc515d32e811a959ca896fd1abd7.zip
FreeBSD-src-e754f74ed01ccc515d32e811a959ca896fd1abd7.tar.gz
MFC r320501:
Correct fences for sys/refcount.h.
-rw-r--r--sys/sys/refcount.h16
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__ */
OpenPOWER on IntegriCloud