From 618a78995848158783640ffa3ef31612cfa0d106 Mon Sep 17 00:00:00 2001 From: Romain Vimont <rom1v@videolabs.io> Date: Thu, 5 Jul 2018 10:30:48 +0200 Subject: [PATCH] core: add atomic refcounter helper Implement an atomic refcounter with a weak but correct (1) memory order, and expose a simple API. (1) See for example "Using weakly ordered C++ atomics correctly" by Hans Boehm at CppCon 2016 (the refcounting part also applies to C11): <https://www.youtube.com/watch?v=M15UKpNlpeM&t=45m15s> Signed-off-by: Steve Lhomme <robux4@ycbcr.xyz> --- include/vlc_atomic.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/vlc_atomic.h b/include/vlc_atomic.h index 868918fe8e62..e2d4fe5360a5 100644 --- a/include/vlc_atomic.h +++ b/include/vlc_atomic.h @@ -30,7 +30,9 @@ * Atomic operations do not require locking, but they are not very powerful. */ +# include <assert.h> # include <stdatomic.h> +# include <vlc_common.h> typedef atomic_uint_least32_t vlc_atomic_float; @@ -57,4 +59,30 @@ static inline void vlc_atomic_store_float(vlc_atomic_float *atom, float f) atomic_store(atom, u.i); } +typedef struct vlc_atomic_rc_t { + atomic_uint refs; +} vlc_atomic_rc_t; + +/** Init the RC to 1 */ +static inline void vlc_atomic_rc_init(vlc_atomic_rc_t *rc) +{ + atomic_init(&rc->refs, 1); +} + +/** Increment the RC */ +static inline void vlc_atomic_rc_inc(vlc_atomic_rc_t *rc) +{ + unsigned prev = atomic_fetch_add_explicit(&rc->refs, 1, memory_order_relaxed); + vlc_assert(prev); + VLC_UNUSED(prev); +} + +/** Decrement the RC and return true if it reaches 0 */ +static inline bool vlc_atomic_rc_dec(vlc_atomic_rc_t *rc) +{ + unsigned prev = atomic_fetch_sub_explicit(&rc->refs, 1, memory_order_acq_rel); + vlc_assert(prev); + return prev == 1; +} + #endif -- GitLab