Skip to content

Commit 157d5e6

Browse files
committed
Correct fences for sys/refcount.h.
The acq barrier in refcount_acquire() has no use, constructor must ensure that the changes are visible before publication by other means. Last release must sync/with the constructor and all updaters. This is based on the refcount/shared_ptr analysis I heard at the Hans Boehm and Herb Sutter talks about C++ atomics. Reviewed by: alc, jhb, markj Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D11270
1 parent cfb2d93 commit 157d5e6

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

sys/sys/refcount.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,28 @@ refcount_acquire(volatile u_int *count)
5050
{
5151

5252
KASSERT(*count < UINT_MAX, ("refcount %p overflowed", count));
53-
atomic_add_acq_int(count, 1);
53+
atomic_add_int(count, 1);
5454
}
5555

5656
static __inline int
5757
refcount_release(volatile u_int *count)
5858
{
5959
u_int old;
6060

61-
/* XXX: Should this have a rel membar? */
61+
atomic_thread_fence_rel();
6262
old = atomic_fetchadd_int(count, -1);
6363
KASSERT(old > 0, ("negative refcount %p", count));
64-
return (old == 1);
64+
if (old > 1)
65+
return (0);
66+
67+
/*
68+
* Last reference. Signal the user to call the destructor.
69+
*
70+
* Ensure that the destructor sees all updates. The fence_rel
71+
* at the start of the function synchronized with this fence.
72+
*/
73+
atomic_thread_fence_acq();
74+
return (1);
6575
}
6676

6777
#endif /* ! __SYS_REFCOUNT_H__ */

0 commit comments

Comments
 (0)