Tor  0.4.7.0-alpha-dev
threads.h
Go to the documentation of this file.
1 /* Copyright (c) 2003-2004, Roger Dingledine
2  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3  * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
5 
6 /**
7  * \file threads.h
8  * \brief Header for threads.c
9  **/
10 
11 #ifndef TOR_COMPAT_THREADS_H
12 #define TOR_COMPAT_THREADS_H
13 
14 #include "orconfig.h"
15 #include "lib/cc/torint.h"
17 #include "lib/lock/compat_mutex.h"
18 
19 #if defined(HAVE_STDATOMIC_H) && defined(STDATOMIC_WORKS)
20 #define HAVE_WORKING_STDATOMIC
21 #endif
22 
23 #ifdef HAVE_WORKING_STDATOMIC
24 #include <stdatomic.h>
25 #endif
26 
27 struct timeval;
28 
29 int spawn_func(void (*func)(void *), void *data);
30 void spawn_exit(void) ATTR_NORETURN;
31 
32 unsigned long tor_get_thread_id(void);
33 void tor_threads_init(void);
34 
35 /** Conditions need nonrecursive mutexes with pthreads. */
36 #define tor_mutex_init_for_cond(m) tor_mutex_init_nonrecursive(m)
37 
38 void set_main_thread(void);
39 int in_main_thread(void);
40 
41 typedef struct tor_cond_t {
42 #ifdef USE_PTHREADS
43  pthread_cond_t cond;
44 #elif defined(USE_WIN32_THREADS)
45  CONDITION_VARIABLE cond;
46 #else
47 #error no known condition implementation.
48 #endif /* defined(USE_PTHREADS) || ... */
49 } tor_cond_t;
50 
52 void tor_cond_free_(tor_cond_t *cond);
53 #define tor_cond_free(c) FREE_AND_NULL(tor_cond_t, tor_cond_free_, (c))
54 int tor_cond_init(tor_cond_t *cond);
55 void tor_cond_uninit(tor_cond_t *cond);
56 int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex,
57  const struct timeval *tv);
60 
61 typedef struct tor_threadlocal_t {
62 #ifdef _WIN32
63  DWORD index;
64 #else
65  pthread_key_t key;
66 #endif
68 
69 /** Initialize a thread-local variable.
70  *
71  * After you call this function on a tor_threadlocal_t, you can call
72  * tor_threadlocal_set to change the current value of this variable for the
73  * current thread, and tor_threadlocal_get to retrieve the current value for
74  * the current thread. Each thread has its own value.
75  **/
76 int tor_threadlocal_init(tor_threadlocal_t *threadlocal);
77 /**
78  * Release all resource associated with a thread-local variable.
79  */
81 /**
82  * Return the current value of a thread-local variable for this thread.
83  *
84  * It's undefined behavior to use this function if the threadlocal hasn't
85  * been initialized, or has been destroyed.
86  */
87 void *tor_threadlocal_get(tor_threadlocal_t *threadlocal);
88 /**
89  * Change the current value of a thread-local variable for this thread to
90  * <b>value</b>.
91  *
92  * It's undefined behavior to use this function if the threadlocal hasn't
93  * been initialized, or has been destroyed.
94  */
95 void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value);
96 
97 /**
98  * Atomic counter type; holds a size_t value.
99  */
100 #ifdef HAVE_WORKING_STDATOMIC
101 typedef struct atomic_counter_t {
102  atomic_size_t val;
104 #ifndef COCCI
105 #define ATOMIC_LINKAGE static
106 #endif
107 #else /* !defined(HAVE_WORKING_STDATOMIC) */
108 typedef struct atomic_counter_t {
109  tor_mutex_t mutex;
110  size_t val;
112 #define ATOMIC_LINKAGE
113 #endif /* defined(HAVE_WORKING_STDATOMIC) */
114 
115 ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter);
116 ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter);
117 ATOMIC_LINKAGE void atomic_counter_add(atomic_counter_t *counter, size_t add);
118 ATOMIC_LINKAGE void atomic_counter_sub(atomic_counter_t *counter, size_t sub);
119 ATOMIC_LINKAGE size_t atomic_counter_get(atomic_counter_t *counter);
120 ATOMIC_LINKAGE size_t atomic_counter_exchange(atomic_counter_t *counter,
121  size_t newval);
122 #undef ATOMIC_LINKAGE
123 
124 #ifdef HAVE_WORKING_STDATOMIC
125 /** Initialize a new atomic counter with the value 0 */
126 static inline void
128 {
129  atomic_init(&counter->val, 0);
130 }
131 /** Clean up all resources held by an atomic counter.
132  *
133  * This usage note applies to the compat_threads implementation of
134  * atomic_counter_destroy():
135  * Destroying a locked mutex is undefined behaviour. Global mutexes may be
136  * locked when they are passed to this function, because multiple threads can
137  * still access them. So we can either:
138  * - destroy on shutdown, and re-initialise when tor re-initialises, or
139  * - skip destroying and re-initialisation, using a sentinel variable.
140  * See #31735 for details.
141  */
142 static inline void
144 {
145  (void)counter;
146 }
147 /** Add a value to an atomic counter. */
148 static inline void
149 atomic_counter_add(atomic_counter_t *counter, size_t add)
150 {
151  (void) atomic_fetch_add(&counter->val, add);
152 }
153 /** Subtract a value from an atomic counter. */
154 static inline void
155 atomic_counter_sub(atomic_counter_t *counter, size_t sub)
156 {
157  (void) atomic_fetch_sub(&counter->val, sub);
158 }
159 /** Return the current value of an atomic counter */
160 static inline size_t
162 {
163  return atomic_load(&counter->val);
164 }
165 /** Replace the value of an atomic counter; return the old one. */
166 static inline size_t
167 atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
168 {
169  return atomic_exchange(&counter->val, newval);
170 }
171 
172 #else /* !defined(HAVE_WORKING_STDATOMIC) */
173 #endif /* defined(HAVE_WORKING_STDATOMIC) */
174 
175 #endif /* !defined(TOR_COMPAT_THREADS_H) */
Header for compat_mutex.c.
Macros to implement mocking and selective exposure for the test code.
ATOMIC_LINKAGE void atomic_counter_add(atomic_counter_t *counter, size_t add)
void tor_cond_free_(tor_cond_t *cond)
ATOMIC_LINKAGE size_t atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter)
void tor_cond_signal_all(tor_cond_t *cond)
void * tor_threadlocal_get(tor_threadlocal_t *threadlocal)
void spawn_exit(void) ATTR_NORETURN
int in_main_thread(void)
int tor_cond_init(tor_cond_t *cond)
int spawn_func(void(*func)(void *), void *data)
ATOMIC_LINKAGE void atomic_counter_sub(atomic_counter_t *counter, size_t sub)
ATOMIC_LINKAGE size_t atomic_counter_get(atomic_counter_t *counter)
void tor_threadlocal_destroy(tor_threadlocal_t *threadlocal)
void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value)
tor_cond_t * tor_cond_new(void)
void tor_threads_init(void)
void set_main_thread(void)
void tor_cond_uninit(tor_cond_t *cond)
void tor_cond_signal_one(tor_cond_t *cond)
int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex, const struct timeval *tv)
int tor_threadlocal_init(tor_threadlocal_t *threadlocal)
unsigned long tor_get_thread_id(void)
ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter)
Integer definitions used throughout Tor.