~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to lib/ovs-thread.h

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <stddef.h>
 
22
#include <sys/types.h>
 
23
#include "ovs-atomic.h"
 
24
#include "util.h"
 
25
 
 
26
 
 
27
/* Mutex. */
 
28
struct OVS_LOCKABLE ovs_mutex {
 
29
    pthread_mutex_t lock;
 
30
    const char *where;
 
31
};
 
32
 
 
33
/* "struct ovs_mutex" initializers:
 
34
 *
 
35
 *    - OVS_MUTEX_INITIALIZER: common case.
 
36
 *
 
37
 *    - OVS_ADAPTIVE_MUTEX_INITIALIZER for a mutex that spins briefly then goes
 
38
 *      to sleeps after some number of iterations.
 
39
 *
 
40
 *    - OVS_ERRORCHECK_MUTEX_INITIALIZER for a mutex that is used for
 
41
 *      error-checking. */
 
42
#define OVS_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, NULL }
 
43
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
 
44
#define OVS_ADAPTIVE_MUTEX_INITIALIZER \
 
45
    { PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, NULL }
 
46
#else
 
47
#define OVS_ADAPTIVE_MUTEX_INITIALIZER OVS_MUTEX_INITIALIZER
 
48
#endif
 
49
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
 
50
#define OVS_ERRORCHECK_MUTEX_INITIALIZER \
 
51
    { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, NULL }
 
52
#else
 
53
#define OVS_ERRORCHECK_MUTEX_INITIALIZER OVS_MUTEX_INITIALIZER
 
54
#endif
 
55
 
 
56
/* Mutex types, suitable for use with pthread_mutexattr_settype().
 
57
 * There is only one nonstandard type:
 
58
 *
 
59
 *    - PTHREAD_MUTEX_ADAPTIVE_NP, the type used for
 
60
 *      OVS_ADAPTIVE_MUTEX_INITIALIZER. */
 
61
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
 
62
#define OVS_MUTEX_ADAPTIVE PTHREAD_MUTEX_ADAPTIVE_NP
 
63
#else
 
64
#define OVS_MUTEX_ADAPTIVE PTHREAD_MUTEX_NORMAL
 
65
#endif
 
66
 
 
67
/* ovs_mutex functions analogous to pthread_mutex_*() functions.
 
68
 *
 
69
 * Most of these functions abort the process with an error message on any
 
70
 * error.  ovs_mutex_trylock() is an exception: it passes through a 0 or EBUSY
 
71
 * return value to the caller and aborts on any other error. */
 
72
void ovs_mutex_init(const struct ovs_mutex *, int type);
 
73
void ovs_mutex_destroy(const struct ovs_mutex *);
 
74
void ovs_mutex_unlock(const struct ovs_mutex *mutex) OVS_RELEASES(mutex);
 
75
void ovs_mutex_lock_at(const struct ovs_mutex *mutex, const char *where)
 
76
    OVS_ACQUIRES(mutex);
 
77
#define ovs_mutex_lock(mutex) \
 
78
        ovs_mutex_lock_at(mutex, SOURCE_LOCATOR)
 
79
 
 
80
int ovs_mutex_trylock_at(const struct ovs_mutex *mutex, const char *where)
 
81
    OVS_TRY_LOCK(0, mutex);
 
82
#define ovs_mutex_trylock(mutex) \
 
83
        ovs_mutex_trylock_at(mutex, SOURCE_LOCATOR)
 
84
 
 
85
void ovs_mutex_cond_wait(pthread_cond_t *, const struct ovs_mutex *);
 
86
 
 
87
/* Wrappers for pthread_mutex_*() that abort the process on any error.
 
88
 * This is still needed when ovs-atomic-pthreads.h is used. */
 
89
void xpthread_mutex_lock(pthread_mutex_t *mutex);
 
90
void xpthread_mutex_unlock(pthread_mutex_t *mutex);
 
91
 
 
92
/* Wrappers for pthread_mutexattr_*() that abort the process on any error. */
 
93
void xpthread_mutexattr_init(pthread_mutexattr_t *);
 
94
void xpthread_mutexattr_destroy(pthread_mutexattr_t *);
 
95
void xpthread_mutexattr_settype(pthread_mutexattr_t *, int type);
 
96
void xpthread_mutexattr_gettype(pthread_mutexattr_t *, int *typep);
 
97
 
 
98
/* Read-write lock. */
 
99
struct OVS_LOCKABLE ovs_rwlock {
 
100
    pthread_rwlock_t lock;
 
101
    const char *where;
 
102
};
 
103
 
 
104
/* Initializer. */
 
105
#define OVS_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER, NULL }
 
106
 
 
107
/* ovs_rwlock functions analogous to pthread_rwlock_*() functions.
 
108
 *
 
109
 * Most of these functions abort the process with an error message on any
 
110
 * error.  The "trylock" functions are exception: they pass through a 0 or
 
111
 * EBUSY return value to the caller and abort on any other error. */
 
112
void ovs_rwlock_init(const struct ovs_rwlock *);
 
113
void ovs_rwlock_destroy(const struct ovs_rwlock *);
 
114
void ovs_rwlock_unlock(const struct ovs_rwlock *rwlock) OVS_RELEASES(rwlock);
 
115
 
 
116
void ovs_rwlock_wrlock_at(const struct ovs_rwlock *rwlock, const char *where)
 
117
    OVS_ACQ_WRLOCK(rwlock);
 
118
#define ovs_rwlock_wrlock(rwlock) \
 
119
        ovs_rwlock_wrlock_at(rwlock, SOURCE_LOCATOR);
 
120
 
 
121
int ovs_rwlock_trywrlock_at(const struct ovs_rwlock *rwlock, const char *where)
 
122
    OVS_TRY_WRLOCK(0, rwlock);
 
123
#define ovs_rwlock_trywrlock(rwlock) \
 
124
    ovs_rwlock_trywrlock_at(rwlock, SOURCE_LOCATOR)
 
125
 
 
126
void ovs_rwlock_rdlock_at(const struct ovs_rwlock *rwlock, const char *where)
 
127
    OVS_ACQ_RDLOCK(rwlock);
 
128
#define ovs_rwlock_rdlock(rwlock) \
 
129
        ovs_rwlock_rdlock_at(rwlock, SOURCE_LOCATOR);
 
130
 
 
131
int ovs_rwlock_tryrdlock_at(const struct ovs_rwlock *rwlock, const char *where)
 
132
    OVS_TRY_RDLOCK(0, rwlock);
 
133
#define ovs_rwlock_tryrdlock(rwlock) \
 
134
        ovs_rwlock_tryrdlock_at(rwlock, SOURCE_LOCATOR)
 
135
 
 
136
/* Wrappers for xpthread_cond_*() that abort the process on any error.
 
137
 *
 
138
 * Use ovs_mutex_cond_wait() to wait for a condition. */
 
139
void xpthread_cond_init(pthread_cond_t *, pthread_condattr_t *);
 
140
void xpthread_cond_destroy(pthread_cond_t *);
 
141
void xpthread_cond_signal(pthread_cond_t *);
 
142
void xpthread_cond_broadcast(pthread_cond_t *);
 
143
 
 
144
#ifdef __CHECKER__
 
145
/* Replace these functions by the macros already defined in the <pthread.h>
 
146
 * annotations, because the macro definitions have correct semantics for the
 
147
 * conditional acquisition that can't be captured in a function annotation.
 
148
 * The difference in semantics from pthread_*() to xpthread_*() does not matter
 
149
 * because sparse is not a compiler. */
 
150
#define xpthread_mutex_trylock pthread_mutex_trylock
 
151
#define xpthread_rwlock_tryrdlock pthread_rwlock_tryrdlock
 
152
#define xpthread_rwlock_trywrlock pthread_rwlock_trywrlock
 
153
#endif
 
154
 
 
155
void xpthread_key_create(pthread_key_t *, void (*destructor)(void *));
 
156
 
 
157
void xpthread_create(pthread_t *, pthread_attr_t *, void *(*)(void *), void *);
 
158
 
 
159
/* Per-thread data.
 
160
 *
 
161
 * Multiple forms of per-thread data exist, each with its own pluses and
 
162
 * minuses:
 
163
 *
 
164
 *     - POSIX per-thread data via pthread_key_t is portable to any pthreads
 
165
 *       implementation, and allows a destructor function to be defined.  It
 
166
 *       only (directly) supports per-thread pointers, which are always
 
167
 *       initialized to NULL.  It requires once-only allocation of a
 
168
 *       pthread_key_t value.  It is relatively slow.
 
169
 *
 
170
 *     - The thread_local feature newly defined in C11 <threads.h> works with
 
171
 *       any data type and initializer, and it is fast.  thread_local does not
 
172
 *       require once-only initialization like pthread_key_t.  C11 does not
 
173
 *       define what happens if one attempts to access a thread_local object
 
174
 *       from a thread other than the one to which that object belongs.  There
 
175
 *       is no provision to call a user-specified destructor when a thread
 
176
 *       ends.
 
177
 *
 
178
 *     - The __thread keyword is a GCC extension similar to thread_local but
 
179
 *       with a longer history.  __thread is not portable to every GCC version
 
180
 *       or environment.  __thread does not restrict the use of a thread-local
 
181
 *       object outside its own thread.
 
182
 *
 
183
 * Here's a handy summary:
 
184
 *
 
185
 *                     pthread_key_t     thread_local       __thread
 
186
 *                     -------------     ------------     -------------
 
187
 * portability             high               low             medium
 
188
 * speed                    low              high               high
 
189
 * supports destructors?    yes                no                 no
 
190
 * needs key allocation?    yes                no                 no
 
191
 * arbitrary initializer?    no               yes                yes
 
192
 * cross-thread access?     yes                no                yes
 
193
 */
 
194
 
 
195
/* DEFINE_PER_THREAD_DATA(TYPE, NAME, INITIALIZER).
 
196
 *
 
197
 * One should prefer to use POSIX per-thread data, via pthread_key_t, when its
 
198
 * performance is acceptable, because of its portability (see the table above).
 
199
 * This macro is an alternatives that takes advantage of thread_local (and
 
200
 * __thread), for its performance, when it is available, and falls back to
 
201
 * POSIX per-thread data otherwise.
 
202
 *
 
203
 * Defines per-thread variable NAME with the given TYPE, initialized to
 
204
 * INITIALIZER (which must be valid as an initializer for a variable with
 
205
 * static lifetime).
 
206
 *
 
207
 * The public interface to the variable is:
 
208
 *
 
209
 *    TYPE *NAME_get(void)
 
210
 *    TYPE *NAME_get_unsafe(void)
 
211
 *
 
212
 *       Returns the address of this thread's instance of NAME.
 
213
 *
 
214
 *       Use NAME_get() in a context where this might be the first use of the
 
215
 *       per-thread variable in the program.  Use NAME_get_unsafe(), which
 
216
 *       avoids a conditional test and is thus slightly faster, in a context
 
217
 *       where one knows that NAME_get() has already been called previously.
 
218
 *
 
219
 * There is no "NAME_set()" (or "NAME_set_unsafe()") function.  To set the
 
220
 * value of the per-thread variable, dereference the pointer returned by
 
221
 * TYPE_get() or TYPE_get_unsafe(), e.g. *TYPE_get() = 0.
 
222
 */
 
223
#if HAVE_THREAD_LOCAL || HAVE___THREAD
 
224
 
 
225
#if HAVE_THREAD_LOCAL
 
226
#include <threads.h>
 
227
#elif HAVE___THREAD
 
228
#define thread_local __thread
 
229
#else
 
230
#error
 
231
#endif
 
232
 
 
233
#define DEFINE_PER_THREAD_DATA(TYPE, NAME, ...)                 \
 
234
    typedef TYPE NAME##_type;                                   \
 
235
    static thread_local NAME##_type NAME##_var = __VA_ARGS__;   \
 
236
                                                                \
 
237
    static NAME##_type *                                        \
 
238
    NAME##_get_unsafe(void)                                     \
 
239
    {                                                           \
 
240
        return &NAME##_var;                                     \
 
241
    }                                                           \
 
242
                                                                \
 
243
    static NAME##_type *                                        \
 
244
    NAME##_get(void)                                            \
 
245
    {                                                           \
 
246
        return NAME##_get_unsafe();                             \
 
247
    }
 
248
#else  /* no C implementation support for thread-local storage  */
 
249
#define DEFINE_PER_THREAD_DATA(TYPE, NAME, ...)                         \
 
250
    typedef TYPE NAME##_type;                                           \
 
251
    static pthread_key_t NAME##_key;                                    \
 
252
                                                                        \
 
253
    static NAME##_type *                                                \
 
254
    NAME##_get_unsafe(void)                                             \
 
255
    {                                                                   \
 
256
        return pthread_getspecific(NAME##_key);                         \
 
257
    }                                                                   \
 
258
                                                                        \
 
259
    static void                                                         \
 
260
    NAME##_once_init(void)                                              \
 
261
    {                                                                   \
 
262
        if (pthread_key_create(&NAME##_key, free)) {                    \
 
263
            abort();                                                    \
 
264
        }                                                               \
 
265
    }                                                                   \
 
266
                                                                        \
 
267
    static NAME##_type *                                                \
 
268
    NAME##_get(void)                                                    \
 
269
    {                                                                   \
 
270
        static pthread_once_t once = PTHREAD_ONCE_INIT;                 \
 
271
        NAME##_type *value;                                             \
 
272
                                                                        \
 
273
        pthread_once(&once, NAME##_once_init);                          \
 
274
        value = NAME##_get_unsafe();                                    \
 
275
        if (!value) {                                                   \
 
276
            static const NAME##_type initial_value = __VA_ARGS__;       \
 
277
                                                                        \
 
278
            value = xmalloc(sizeof *value);                             \
 
279
            *value = initial_value;                                     \
 
280
            pthread_setspecific(NAME##_key, value);                     \
 
281
        }                                                               \
 
282
        return value;                                                   \
 
283
    }
 
284
#endif
 
285
 
 
286
/* DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME).
 
287
 *
 
288
 * This is a simple wrapper around POSIX per-thread data primitives.  It
 
289
 * defines per-thread variable NAME with the given TYPE, which must be a
 
290
 * pointer type.  In each thread, the per-thread variable is initialized to
 
291
 * NULL.  When a thread terminates, the variable is freed with free().
 
292
 *
 
293
 * The public interface to the variable is:
 
294
 *
 
295
 *    TYPE NAME_get(void)
 
296
 *    TYPE NAME_get_unsafe(void)
 
297
 *
 
298
 *       Returns the value of per-thread variable NAME in this thread.
 
299
 *
 
300
 *       Use NAME_get() in a context where this might be the first use of the
 
301
 *       per-thread variable in the program.  Use NAME_get_unsafe(), which
 
302
 *       avoids a conditional test and is thus slightly faster, in a context
 
303
 *       where one knows that NAME_get() has already been called previously.
 
304
 *
 
305
 *    TYPE NAME_set(TYPE new_value)
 
306
 *    TYPE NAME_set_unsafe(TYPE new_value)
 
307
 *
 
308
 *       Sets the value of per-thread variable NAME to 'new_value' in this
 
309
 *       thread, and returns its previous value.
 
310
 *
 
311
 *       Use NAME_set() in a context where this might be the first use of the
 
312
 *       per-thread variable in the program.  Use NAME_set_unsafe(), which
 
313
 *       avoids a conditional test and is thus slightly faster, in a context
 
314
 *       where one knows that NAME_set() has already been called previously.
 
315
 */
 
316
#define DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME)     \
 
317
    static pthread_key_t NAME##_key;                    \
 
318
                                                        \
 
319
    static void                                         \
 
320
    NAME##_once_init(void)                              \
 
321
    {                                                   \
 
322
        if (pthread_key_create(&NAME##_key, free)) {    \
 
323
            abort();                                    \
 
324
        }                                               \
 
325
    }                                                   \
 
326
                                                        \
 
327
    static void                                         \
 
328
    NAME##_init(void)                                   \
 
329
    {                                                   \
 
330
        static pthread_once_t once = PTHREAD_ONCE_INIT; \
 
331
        pthread_once(&once, NAME##_once_init);          \
 
332
    }                                                   \
 
333
                                                        \
 
334
    static TYPE                                         \
 
335
    NAME##_get_unsafe(void)                             \
 
336
    {                                                   \
 
337
        return pthread_getspecific(NAME##_key);         \
 
338
    }                                                   \
 
339
                                                        \
 
340
    static OVS_UNUSED TYPE                              \
 
341
    NAME##_get(void)                                    \
 
342
    {                                                   \
 
343
        NAME##_init();                                  \
 
344
        return NAME##_get_unsafe();                     \
 
345
    }                                                   \
 
346
                                                        \
 
347
    static TYPE                                         \
 
348
    NAME##_set_unsafe(TYPE value)                       \
 
349
    {                                                   \
 
350
        TYPE old_value = NAME##_get_unsafe();           \
 
351
        pthread_setspecific(NAME##_key, value);         \
 
352
        return old_value;                               \
 
353
    }                                                   \
 
354
                                                        \
 
355
    static OVS_UNUSED TYPE                              \
 
356
    NAME##_set(TYPE value)                              \
 
357
    {                                                   \
 
358
        NAME##_init();                                  \
 
359
        return NAME##_set_unsafe(value);                \
 
360
    }
 
361
 
 
362
/* Convenient once-only execution.
 
363
 *
 
364
 *
 
365
 * Problem
 
366
 * =======
 
367
 *
 
368
 * POSIX provides pthread_once_t and pthread_once() as primitives for running a
 
369
 * set of code only once per process execution.  They are used like this:
 
370
 *
 
371
 *     static void run_once(void) { ...initialization... }
 
372
 *     static pthread_once_t once = PTHREAD_ONCE_INIT;
 
373
 * ...
 
374
 *     pthread_once(&once, run_once);
 
375
 *
 
376
 * pthread_once() does not allow passing any parameters to the initialization
 
377
 * function, which is often inconvenient, because it means that the function
 
378
 * can only access data declared at file scope.
 
379
 *
 
380
 *
 
381
 * Solution
 
382
 * ========
 
383
 *
 
384
 * Use ovsthread_once, like this, instead:
 
385
 *
 
386
 *     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
 
387
 *
 
388
 *     if (ovsthread_once_start(&once)) {
 
389
 *         ...initialization...
 
390
 *         ovsthread_once_done(&once);
 
391
 *     }
 
392
 */
 
393
 
 
394
struct ovsthread_once {
 
395
    atomic_bool done;
 
396
    struct ovs_mutex mutex;
 
397
};
 
398
 
 
399
#define OVSTHREAD_ONCE_INITIALIZER              \
 
400
    {                                           \
 
401
        ATOMIC_VAR_INIT(false),                 \
 
402
        OVS_ADAPTIVE_MUTEX_INITIALIZER,         \
 
403
    }
 
404
 
 
405
static inline bool ovsthread_once_start(struct ovsthread_once *once)
 
406
    OVS_TRY_LOCK(true, &once->mutex);
 
407
void ovsthread_once_done(struct ovsthread_once *once)
 
408
    OVS_RELEASES(&once->mutex);
 
409
 
 
410
bool ovsthread_once_start__(struct ovsthread_once *once)
 
411
    OVS_TRY_LOCK(false, &once->mutex);
 
412
 
 
413
static inline bool
 
414
ovsthread_once_is_done__(const struct ovsthread_once *once)
 
415
{
 
416
    bool done;
 
417
 
 
418
    atomic_read_explicit(&once->done, &done, memory_order_relaxed);
 
419
    return done;
 
420
}
 
421
 
 
422
/* Returns true if this is the first call to ovsthread_once_start() for
 
423
 * 'once'.  In this case, the caller should perform whatever initialization
 
424
 * actions it needs to do, then call ovsthread_once_done() for 'once'.
 
425
 *
 
426
 * Returns false if this is not the first call to ovsthread_once_start() for
 
427
 * 'once'.  In this case, the call will not return until after
 
428
 * ovsthread_once_done() has been called. */
 
429
static inline bool
 
430
ovsthread_once_start(struct ovsthread_once *once)
 
431
{
 
432
    return OVS_UNLIKELY(!ovsthread_once_is_done__(once)
 
433
                        && !ovsthread_once_start__(once));
 
434
}
 
435
 
 
436
#ifdef __CHECKER__
 
437
#define ovsthread_once_start(ONCE) \
 
438
    ((ONCE)->done ? false : ({ OVS_MACRO_LOCK((&ONCE->mutex)); true; }))
 
439
#endif
 
440
 
 
441
void assert_single_threaded(const char *where);
 
442
#define assert_single_threaded() assert_single_threaded(SOURCE_LOCATOR)
 
443
 
 
444
pid_t xfork(const char *where);
 
445
#define xfork() xfork(SOURCE_LOCATOR)
 
446
 
 
447
void forbid_forking(const char *reason);
 
448
bool may_fork(void);
 
449
 
 
450
#endif /* ovs-thread.h */