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
This commit is contained in:
parent
cfb2d93ba6
commit
157d5e6df3
@ -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__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user