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 | |
parent | 8b3580255d7b653cc20476c4294b2e47af351f79 (diff) | |
parent | 25f882a9cfe39ccb2942fe55f41cdcbfd1ba288e (diff) | |
download | tor-5da0a73838a210bac3be81baa9ade1d4ee7bf343.tar.gz tor-5da0a73838a210bac3be81baa9ade1d4ee7bf343.zip |
Merge branch 'ticket23953_033_squashed'
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat_threads.c | 19 | ||||
-rw-r--r-- | src/common/compat_threads.h | 66 |
2 files changed, 74 insertions, 11 deletions
diff --git a/src/common/compat_threads.c b/src/common/compat_threads.c index 208d3138d9..e8a97f1254 100644 --- a/src/common/compat_threads.c +++ b/src/common/compat_threads.c @@ -352,12 +352,7 @@ alert_sockets_close(alert_sockets_t *socks) socks->read_fd = socks->write_fd = -1; } -/* - * XXXX We might be smart to move to compiler intrinsics or real atomic - * XXXX operations at some point. But not yet. - * - */ - +#ifndef HAVE_STDATOMIC_H /** Initialize a new atomic counter with the value 0 */ void atomic_counter_init(atomic_counter_t *counter) @@ -397,4 +392,16 @@ atomic_counter_get(atomic_counter_t *counter) tor_mutex_release(&counter->mutex); return val; } +/** Replace the value of an atomic counter; return the old one. */ +size_t +atomic_counter_exchange(atomic_counter_t *counter, size_t newval) +{ + size_t oldval; + tor_mutex_acquire(&counter->mutex); + oldval = counter->val; + counter->val = newval; + tor_mutex_release(&counter->mutex); + return oldval; +} +#endif 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) */ |