Tor 0.4.9.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"
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
27struct timeval;
28
29int spawn_func(void (*func)(void *), void *data);
30void spawn_exit(void) ATTR_NORETURN;
31
32unsigned long tor_get_thread_id(void);
33void 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
38void set_main_thread(void);
39int in_main_thread(void);
40
41typedef 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) || ... */
50
52void tor_cond_free_(tor_cond_t *cond);
53#define tor_cond_free(c) FREE_AND_NULL(tor_cond_t, tor_cond_free_, (c))
54int tor_cond_init(tor_cond_t *cond);
55void tor_cond_uninit(tor_cond_t *cond);
56int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex,
57 const struct timeval *tv);
60
61typedef 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 **/
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 */
87void *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 */
95void 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
101typedef 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) */
108typedef struct atomic_counter_t {
109 tor_mutex_t mutex;
110 size_t val;
112#define ATOMIC_LINKAGE
113#endif /* defined(HAVE_WORKING_STDATOMIC) */
114
115ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter);
116ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter);
117ATOMIC_LINKAGE void atomic_counter_add(atomic_counter_t *counter, size_t add);
118ATOMIC_LINKAGE void atomic_counter_sub(atomic_counter_t *counter, size_t sub);
119ATOMIC_LINKAGE size_t atomic_counter_get(atomic_counter_t *counter);
120ATOMIC_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 */
126static 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 */
142static inline void
144{
145 (void)counter;
146}
147/** Add a value to an atomic counter. */
148static inline void
149atomic_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. */
154static inline void
155atomic_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 */
160static inline size_t
162{
163 return atomic_load(&counter->val);
164}
165/** Replace the value of an atomic counter; return the old one. */
166static inline size_t
167atomic_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 spawn_exit(void) ATTR_NORETURN
void * tor_threadlocal_get(tor_threadlocal_t *threadlocal)
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)
void tor_threads_init(void)
void set_main_thread(void)
tor_cond_t * tor_cond_new(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.