summaryrefslogtreecommitdiff
path: root/src/common/compat_threads.h
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2017-11-21 14:06:57 -0500
committerNick Mathewson <nickm@torproject.org>2017-11-21 14:06:57 -0500
commit5da0a73838a210bac3be81baa9ade1d4ee7bf343 (patch)
tree0b5f5c246bbfcf27501c846cc2ebe8cae4f97773 /src/common/compat_threads.h
parent8b3580255d7b653cc20476c4294b2e47af351f79 (diff)
parent25f882a9cfe39ccb2942fe55f41cdcbfd1ba288e (diff)
downloadtor-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.h66
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) */