| 
														
															@@ -14,6 +14,10 @@ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #include <pthread.h> 
														 | 
														
														 | 
														
															 #include <pthread.h> 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #endif 
														 | 
														
														 | 
														
															 #endif 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#ifdef HAVE_STDATOMIC_H 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#include <stdatomic.h> 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+#endif 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #if defined(_WIN32) 
														 | 
														
														 | 
														
															 #if defined(_WIN32) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #define USE_WIN32_THREADS 
														 | 
														
														 | 
														
															 #define USE_WIN32_THREADS 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 #elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE) 
														 | 
														
														 | 
														
															 #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. 
														 | 
														
														 | 
														
															  * 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 { 
														 | 
														
														 | 
														
															 typedef struct atomic_counter_t { 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   tor_mutex_t mutex; 
														 | 
														
														 | 
														
															   tor_mutex_t mutex; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															   size_t val; 
														 | 
														
														 | 
														
															   size_t val; 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 } atomic_counter_t; 
														 | 
														
														 | 
														
															 } 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) */ 
														 | 
														
														 | 
														
															 #endif /* !defined(TOR_COMPAT_THREADS_H) */ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 |