From a503b8859c37906ab5012db163daca43bfe393bb Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Sat, 21 May 2011 17:35:21 -0700 Subject: Make all handlers objects refcounted. I'm realizing that basically all upb objects will need to be refcounted to be sharable across languages, but *not* messages which are on their way out so we can get out of the business of data representations. Things which must be refcounted: - encoders, decoders - handlers objects - defs --- src/upb_atomic.h | 52 ++++++++++++++++++---------------------------------- 1 file changed, 18 insertions(+), 34 deletions(-) (limited to 'src/upb_atomic.h') diff --git a/src/upb_atomic.h b/src/upb_atomic.h index b1ba60d..53501b5 100644 --- a/src/upb_atomic.h +++ b/src/upb_atomic.h @@ -39,35 +39,19 @@ extern "C" { typedef struct { int v; -} upb_atomic_refcount_t; +} upb_atomic_t; -INLINE void upb_atomic_refcount_init(upb_atomic_refcount_t *a, int val) { - a->v = val; -} - -INLINE bool upb_atomic_ref(upb_atomic_refcount_t *a) { - return a->v++ == 0; -} - -INLINE bool upb_atomic_unref(upb_atomic_refcount_t *a) { - return --a->v == 0; -} +#define UPB_ATOMIC_INIT(x) {x} -INLINE int upb_atomic_read(upb_atomic_refcount_t *a) { - return a->v; -} - -INLINE bool upb_atomic_add(upb_atomic_refcount_t *a, int val) { +INLINE void upb_atomic_init(upb_atomic_t *a, int val) { a->v = val; } +INLINE bool upb_atomic_ref(upb_atomic_t *a) { return a->v++ == 0; } +INLINE bool upb_atomic_unref(upb_atomic_t *a) { return --a->v == 0; } +INLINE int upb_atomic_read(upb_atomic_t *a) { return a->v; } +INLINE bool upb_atomic_add(upb_atomic_t *a, int val) { a->v += val; return a->v == 0; } -INLINE int upb_atomic_fetch_and_add(upb_atomic_refcount_t *a, int val) { - int ret = a->v; - a->v += val; - return ret; -} - #endif /* Atomic refcount ************************************************************/ @@ -82,26 +66,26 @@ INLINE int upb_atomic_fetch_and_add(upb_atomic_refcount_t *a, int val) { typedef struct { volatile int v; -} upb_atomic_refcount_t; +} upb_atomic_t; -INLINE void upb_atomic_refcount_init(upb_atomic_refcount_t *a, int val) { +INLINE void upb_atomic_init(upb_atomic_t *a, int val) { a->v = val; __sync_synchronize(); /* Ensure the initialized value is visible. */ } -INLINE bool upb_atomic_ref(upb_atomic_refcount_t *a) { +INLINE bool upb_atomic_ref(upb_atomic_t *a) { return __sync_fetch_and_add(&a->v, 1) == 0; } -INLINE bool upb_atomic_add(upb_atomic_refcount_t *a, int n) { +INLINE bool upb_atomic_add(upb_atomic_t *a, int n) { return __sync_add_and_fetch(&a->v, n) == 0; } -INLINE bool upb_atomic_unref(upb_atomic_refcount_t *a) { +INLINE bool upb_atomic_unref(upb_atomic_t *a) { return __sync_sub_and_fetch(&a->v, 1) == 0; } -INLINE bool upb_atomic_read(upb_atomic_refcount_t *a) { +INLINE bool upb_atomic_read(upb_atomic_t *a) { return __sync_fetch_and_add(&a->v, 0); } @@ -112,17 +96,17 @@ INLINE bool upb_atomic_read(upb_atomic_refcount_t *a) { typedef struct { volatile LONG val; -} upb_atomic_refcount_t; +} upb_atomic_t; -INLINE void upb_atomic_refcount_init(upb_atomic_refcount_t *a, int val) { +INLINE void upb_atomic_init(upb_atomic_t *a, int val) { InterlockedExchange(&a->val, val); } -INLINE bool upb_atomic_ref(upb_atomic_refcount_t *a) { +INLINE bool upb_atomic_ref(upb_atomic_t *a) { return InterlockedIncrement(&a->val) == 1; } -INLINE bool upb_atomic_unref(upb_atomic_refcount_t *a) { +INLINE bool upb_atomic_unref(upb_atomic_t *a) { return InterlockedDecrement(&a->val) == 0; } @@ -131,7 +115,7 @@ INLINE bool upb_atomic_unref(upb_atomic_refcount_t *a) { Implement them or compile with UPB_THREAD_UNSAFE. #endif -INLINE bool upb_atomic_only(upb_atomic_refcount_t *a) { +INLINE bool upb_atomic_only(upb_atomic_t *a) { return upb_atomic_read(a) == 1; } -- cgit v1.2.3