diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-11-21 14:06:57 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-11-21 14:06:57 -0500 |
commit | 5da0a73838a210bac3be81baa9ade1d4ee7bf343 (patch) | |
tree | 0b5f5c246bbfcf27501c846cc2ebe8cae4f97773 /src/common/compat_threads.h | |
parent | 8b3580255d7b653cc20476c4294b2e47af351f79 (diff) | |
parent | 25f882a9cfe39ccb2942fe55f41cdcbfd1ba288e (diff) | |
download | tor-5da0a73838a210bac3be81baa9ade1d4ee7bf343.tar.gz tor-5da0a73838a210bac3be81baa9ade1d4ee7bf343.zip |
Merge branch 'ticket23953_033_squashed'
Diffstat (limited to 'src/common/compat_threads.h')
-rw-r--r-- | src/common/compat_threads.h | 66 |
1 files changed, 61 insertions, 5 deletions
diff --git a/src/common/compat_threads.h b/src/common/compat_threads.h index 42f14eab2a..b452648ea5 100644 --- a/src/common/compat_threads.h +++ b/src/common/compat_threads.h @@ -14,6 +14,10 @@ #include <pthread.h> #endif +#ifdef HAVE_STDATOMIC_H +#include <stdatomic.h> +#endif + #if defined(_WIN32) #define USE_WIN32_THREADS #elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE) @@ -150,16 +154,68 @@ void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value); /** * Atomic counter type; holds a size_t value. */ +#ifdef HAVE_STDATOMIC_H +typedef struct atomic_counter_t { + atomic_size_t val; +} atomic_counter_t; +#define ATOMIC_LINKAGE static +#else typedef struct atomic_counter_t { tor_mutex_t mutex; size_t val; } atomic_counter_t; +#define ATOMIC_LINKAGE +#endif + +ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter); +ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter); +ATOMIC_LINKAGE void atomic_counter_add(atomic_counter_t *counter, size_t add); +ATOMIC_LINKAGE void atomic_counter_sub(atomic_counter_t *counter, size_t sub); +ATOMIC_LINKAGE size_t atomic_counter_get(atomic_counter_t *counter); +ATOMIC_LINKAGE size_t atomic_counter_exchange(atomic_counter_t *counter, + size_t newval); +#undef ATOMIC_LINKAGE + +#ifdef HAVE_STDATOMIC_H +/** Initialize a new atomic counter with the value 0 */ +static inline void +atomic_counter_init(atomic_counter_t *counter) +{ + atomic_init(&counter->val, 0); +} +/** Clean up all resources held by an atomic counter. */ +static inline void +atomic_counter_destroy(atomic_counter_t *counter) +{ + (void)counter; +} +/** Add a value to an atomic counter. */ +static inline void +atomic_counter_add(atomic_counter_t *counter, size_t add) +{ + (void) atomic_fetch_add(&counter->val, add); +} +/** Subtract a value from an atomic counter. */ +static inline void +atomic_counter_sub(atomic_counter_t *counter, size_t sub) +{ + (void) atomic_fetch_sub(&counter->val, sub); +} +/** Return the current value of an atomic counter */ +static inline size_t +atomic_counter_get(atomic_counter_t *counter) +{ + return atomic_load(&counter->val); +} +/** Replace the value of an atomic counter; return the old one. */ +static inline size_t +atomic_counter_exchange(atomic_counter_t *counter, size_t newval) +{ + return atomic_exchange(&counter->val, newval); +} -void atomic_counter_init(atomic_counter_t *counter); -void atomic_counter_destroy(atomic_counter_t *counter); -void atomic_counter_add(atomic_counter_t *counter, size_t add); -void atomic_counter_sub(atomic_counter_t *counter, size_t sub); -size_t atomic_counter_get(atomic_counter_t *counter); +#else +#endif #endif /* !defined(TOR_COMPAT_THREADS_H) */ |