ovs-thread: Add per-thread data support.
[sliver-openvswitch.git] / lib / ovs-thread.h
1 /*
2  * Copyright (c) 2013 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef OVS_THREAD_H
18 #define OVS_THREAD_H 1
19
20 #include <pthread.h>
21 #include "util.h"
22
23 /* glibc has some non-portable mutex types and initializers:
24  *
25  *    - PTHREAD_MUTEX_ADAPTIVE_NP is a mutex type that works as a spinlock that
26  *      falls back to a mutex after spinning for some number of iterations.
27  *
28  *    - PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP is a non-portable initializer
29  *      for an error-checking mutex.
30  *
31  * We use these definitions to fall back to PTHREAD_MUTEX_NORMAL instead in
32  * these cases.
33  *
34  * (glibc has other non-portable initializers, but we can't reasonably
35  * substitute for them here.) */
36 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
37 #define PTHREAD_MUTEX_ADAPTIVE PTHREAD_MUTEX_ADAPTIVE_NP
38 #define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER \
39     PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
40 #else
41 #define PTHREAD_MUTEX_ADAPTIVE PTHREAD_MUTEX_NORMAL
42 #define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
43 #endif
44
45 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
46 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER \
47     PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
48 #else
49 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
50 #endif
51 \f
52 /* Simple wrappers for pthreads functions.  Most of these functions abort the
53  * process with an error message on any error.  The *_trylock() functions are
54  * exceptions: they pass through a 0 or EBUSY return value to the caller and
55  * abort on any other error. */
56 void xpthread_mutex_init(pthread_mutex_t *, pthread_mutexattr_t *);
57 void xpthread_mutex_lock(pthread_mutex_t *mutex) OVS_ACQUIRES(mutex);
58 void xpthread_mutex_unlock(pthread_mutex_t *mutex) OVS_RELEASES(mutex);
59 int xpthread_mutex_trylock(pthread_mutex_t *);
60
61 void xpthread_rwlock_init(pthread_rwlock_t *, pthread_rwlockattr_t *);
62 void xpthread_rwlock_rdlock(pthread_rwlock_t *rwlock) OVS_ACQUIRES(rwlock);
63 void xpthread_rwlock_wrlock(pthread_rwlock_t *rwlock) OVS_ACQUIRES(rwlock);
64 void xpthread_rwlock_unlock(pthread_rwlock_t *rwlock) OVS_RELEASES(rwlock);
65 int xpthread_rwlock_tryrdlock(pthread_rwlock_t *);
66 int xpthread_rwlock_trywrlock(pthread_rwlock_t *);
67
68 void xpthread_cond_init(pthread_cond_t *, pthread_condattr_t *);
69 void xpthread_cond_signal(pthread_cond_t *);
70 void xpthread_cond_broadcast(pthread_cond_t *);
71 void xpthread_cond_wait(pthread_cond_t *, pthread_mutex_t *mutex)
72     OVS_MUST_HOLD(mutex);
73
74 #ifdef __CHECKER__
75 /* Replace these functions by the macros already defined in the <pthread.h>
76  * annotations, because the macro definitions have correct semantics for the
77  * conditional acquisition that can't be captured in a function annotation.
78  * The difference in semantics from pthread_*() to xpthread_*() does not matter
79  * because sparse is not a compiler. */
80 #define xpthread_mutex_trylock pthread_mutex_trylock
81 #define xpthread_rwlock_tryrdlock pthread_rwlock_tryrdlock
82 #define xpthread_rwlock_trywrlock pthread_rwlock_trywrlock
83 #endif
84
85 void xpthread_key_create(pthread_key_t *, void (*destructor)(void *));
86
87 void xpthread_create(pthread_t *, pthread_attr_t *, void *(*)(void *), void *);
88 \f
89 /* Per-thread data.
90  *
91  * Multiple forms of per-thread data exist, each with its own pluses and
92  * minuses:
93  *
94  *     - POSIX per-thread data via pthread_key_t is portable to any pthreads
95  *       implementation, and allows a destructor function to be defined.  It
96  *       only (directly) supports per-thread pointers, which are always
97  *       initialized to NULL.  It requires once-only allocation of a
98  *       pthread_key_t value.  It is relatively slow.
99  *
100  *     - The thread_local feature newly defined in C11 <threads.h> works with
101  *       any data type and initializer, and it is fast.  thread_local does not
102  *       require once-only initialization like pthread_key_t.  C11 does not
103  *       define what happens if one attempts to access a thread_local object
104  *       from a thread other than the one to which that object belongs.  There
105  *       is no provision to call a user-specified destructor when a thread
106  *       ends.
107  *
108  *     - The __thread keyword is a GCC extension similar to thread_local but
109  *       with a longer history.  __thread is not portable to every GCC version
110  *       or environment.  __thread does not restrict the use of a thread-local
111  *       object outside its own thread.
112  *
113  * Here's a handy summary:
114  *
115  *                     pthread_key_t     thread_local       __thread
116  *                     -------------     ------------     -------------
117  * portability             high               low             medium
118  * speed                    low              high               high
119  * supports destructors?    yes                no                 no
120  * needs key allocation?    yes                no                 no
121  * arbitrary initializer?    no               yes                yes
122  * cross-thread access?     yes                no                yes
123  */
124
125 /* DEFINE_PER_THREAD_DATA(TYPE, NAME, INITIALIZER).
126  *
127  * One should prefer to use POSIX per-thread data, via pthread_key_t, when its
128  * performance is acceptable, because of its portability (see the table above).
129  * This macro is an alternatives that takes advantage of thread_local (and
130  * __thread), for its performance, when it is available, and falls back to
131  * POSIX per-thread data otherwise.
132  *
133  * Defines per-thread variable NAME with the given TYPE, initialized to
134  * INITIALIZER (which must be valid as an initializer for a variable with
135  * static lifetime).
136  *
137  * The public interface to the variable is:
138  *
139  *    TYPE *NAME_get(void)
140  *    TYPE *NAME_get_unsafe(void)
141  *
142  *       Returns the address of this thread's instance of NAME.
143  *
144  *       Use NAME_get() in a context where this might be the first use of the
145  *       per-thread variable in the program.  Use NAME_get_unsafe(), which
146  *       avoids a conditional test and is thus slightly faster, in a context
147  *       where one knows that NAME_get() has already been called previously.
148  *
149  * There is no "NAME_set()" (or "NAME_set_unsafe()") function.  To set the
150  * value of the per-thread variable, dereference the pointer returned by
151  * TYPE_get() or TYPE_get_unsafe(), e.g. *TYPE_get() = 0.
152  */
153 #if HAVE_THREAD_LOCAL || HAVE___THREAD
154
155 #if HAVE_THREAD_LOCAL
156 #include <threads.h>
157 #elif HAVE___THREAD
158 #define thread_local __thread
159 #else
160 #error
161 #endif
162
163 #define DEFINE_PER_THREAD_DATA(TYPE, NAME, ...)                 \
164     typedef TYPE NAME##_type;                                   \
165     static thread_local NAME##_type NAME##_var = __VA_ARGS__;   \
166                                                                 \
167     static NAME##_type *                                        \
168     NAME##_get_unsafe(void)                                     \
169     {                                                           \
170         return &NAME##_var;                                     \
171     }                                                           \
172                                                                 \
173     static NAME##_type *                                        \
174     NAME##_get(void)                                            \
175     {                                                           \
176         return NAME##_get_unsafe();                             \
177     }
178 #else  /* no C implementation support for thread-local storage  */
179 #define DEFINE_PER_THREAD_DATA(TYPE, NAME, ...)                         \
180     typedef TYPE NAME##_type;                                           \
181     static pthread_key_t NAME##_key;                                    \
182                                                                         \
183     static NAME##_type *                                                \
184     NAME##_get_unsafe(void)                                             \
185     {                                                                   \
186         return pthread_getspecific(NAME##_key);                         \
187     }                                                                   \
188                                                                         \
189     static void                                                         \
190     NAME##_once_init(void)                                              \
191     {                                                                   \
192         if (pthread_key_create(&NAME##_key, free)) {                    \
193             abort();                                                    \
194         }                                                               \
195     }                                                                   \
196                                                                         \
197     static NAME##_type *                                                \
198     NAME##_get(void)                                                    \
199     {                                                                   \
200         static pthread_once_t once = PTHREAD_ONCE_INIT;                 \
201         NAME##_type *value;                                             \
202                                                                         \
203         pthread_once(&once, NAME##_once_init);                          \
204         value = NAME##_get_unsafe();                                    \
205         if (!value) {                                                   \
206             static const NAME##_type initial_value = __VA_ARGS__;       \
207                                                                         \
208             value = xmalloc(sizeof *value);                             \
209             *value = initial_value;                                     \
210             pthread_setspecific(NAME##_key, value);                     \
211         }                                                               \
212         return value;                                                   \
213     }
214 #endif
215
216 /* DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME).
217  *
218  * This is a simple wrapper around POSIX per-thread data primitives.  It
219  * defines per-thread variable NAME with the given TYPE, which must be a
220  * pointer type.  In each thread, the per-thread variable is initialized to
221  * NULL.  When a thread terminates, the variable is freed with free().
222  *
223  * The public interface to the variable is:
224  *
225  *    TYPE NAME_get(void)
226  *    TYPE NAME_get_unsafe(void)
227  *
228  *       Returns the value of per-thread variable NAME in this thread.
229  *
230  *       Use NAME_get() in a context where this might be the first use of the
231  *       per-thread variable in the program.  Use NAME_get_unsafe(), which
232  *       avoids a conditional test and is thus slightly faster, in a context
233  *       where one knows that NAME_get() has already been called previously.
234  *
235  *    TYPE NAME_set(TYPE new_value)
236  *    TYPE NAME_set_unsafe(TYPE new_value)
237  *
238  *       Sets the value of per-thread variable NAME to 'new_value' in this
239  *       thread, and returns its previous value.
240  *
241  *       Use NAME_set() in a context where this might be the first use of the
242  *       per-thread variable in the program.  Use NAME_set_unsafe(), which
243  *       avoids a conditional test and is thus slightly faster, in a context
244  *       where one knows that NAME_set() has already been called previously.
245  */
246 #define DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME)     \
247     static pthread_key_t NAME##_key;                    \
248                                                         \
249     static void                                         \
250     NAME##_once_init(void)                              \
251     {                                                   \
252         if (pthread_key_create(&NAME##_key, free)) {    \
253             abort();                                    \
254         }                                               \
255     }                                                   \
256                                                         \
257     static void                                         \
258     NAME##_init(void)                                   \
259     {                                                   \
260         static pthread_once_t once = PTHREAD_ONCE_INIT; \
261         pthread_once(&once, NAME##_once_init);          \
262     }                                                   \
263                                                         \
264     static TYPE                                         \
265     NAME##_get_unsafe(void)                             \
266     {                                                   \
267         return pthread_getspecific(NAME##_key);         \
268     }                                                   \
269                                                         \
270     static OVS_UNUSED TYPE                              \
271     NAME##_get(void)                                    \
272     {                                                   \
273         NAME##_init();                                  \
274         return NAME##_get_unsafe();                     \
275     }                                                   \
276                                                         \
277     static TYPE                                         \
278     NAME##_set_unsafe(TYPE value)                       \
279     {                                                   \
280         TYPE old_value = NAME##_get_unsafe();           \
281         pthread_setspecific(NAME##_key, value);         \
282         return old_value;                               \
283     }                                                   \
284                                                         \
285     static OVS_UNUSED TYPE                              \
286     NAME##_set(TYPE value)                              \
287     {                                                   \
288         NAME##_init();                                  \
289         return NAME##_set_unsafe(value);                \
290     }
291 \f
292
293 #endif /* ovs-thread.h */