~ubuntu-branches/ubuntu/wily/openvswitch/wily

« back to all changes in this revision

Viewing changes to lib/ovs-thread.h

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-08-10 11:35:15 UTC
  • mfrom: (1.1.30)
  • Revision ID: package-import@ubuntu.com-20150810113515-575vj06oq29emxsn
Tags: 2.4.0~git20150810.97bab95-0ubuntu1
* New upstream snapshot from 2.4 branch:
  - d/*: Align any relevant packaging changes with upstream.
* d/*: wrap-and-sort.
* d/openvswitch-{common,vswitch}.install: Correct install location for
  bash completion files.
* d/tests/openflow.py: Explicitly use ovs-testcontroller as provided
  by 2.4.0 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include <stddef.h>
22
22
#include <sys/types.h>
23
23
#include "ovs-atomic.h"
 
24
#include "openvswitch/thread.h"
24
25
#include "util.h"
25
26
 
26
27
struct seq;
27
28
 
28
 
/* Mutex. */
29
 
struct OVS_LOCKABLE ovs_mutex {
30
 
    pthread_mutex_t lock;
31
 
    const char *where;          /* NULL if and only if uninitialized. */
32
 
};
33
 
 
34
29
/* Poll-block()-able barrier similar to pthread_barrier_t. */
35
30
struct ovs_barrier {
36
31
    uint32_t size;            /* Number of threads to wait. */
37
 
    atomic_uint32_t count;    /* Number of threads already hit the barrier. */
 
32
    atomic_count count;       /* Number of threads already hit the barrier. */
38
33
    struct seq *seq;
39
34
};
40
35
 
41
 
/* "struct ovs_mutex" initializer. */
42
 
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
43
 
#define OVS_MUTEX_INITIALIZER { PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP, \
44
 
                                "<unlocked>" }
45
 
#else
46
 
#define OVS_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, "<unlocked>" }
47
 
#endif
48
 
 
49
 
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
50
 
#define OVS_ADAPTIVE_MUTEX_INITIALIZER                  \
51
 
    { PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, "<unlocked>" }
52
 
#else
53
 
#define OVS_ADAPTIVE_MUTEX_INITIALIZER OVS_MUTEX_INITIALIZER
54
 
#endif
55
 
 
56
 
/* ovs_mutex functions analogous to pthread_mutex_*() functions.
57
 
 *
58
 
 * Most of these functions abort the process with an error message on any
59
 
 * error.  ovs_mutex_trylock() is an exception: it passes through a 0 or EBUSY
60
 
 * return value to the caller and aborts on any other error. */
61
 
void ovs_mutex_init(const struct ovs_mutex *);
62
 
void ovs_mutex_init_recursive(const struct ovs_mutex *);
63
 
void ovs_mutex_init_adaptive(const struct ovs_mutex *);
64
 
void ovs_mutex_destroy(const struct ovs_mutex *);
65
 
void ovs_mutex_unlock(const struct ovs_mutex *mutex) OVS_RELEASES(mutex);
66
 
void ovs_mutex_lock_at(const struct ovs_mutex *mutex, const char *where)
67
 
    OVS_ACQUIRES(mutex);
68
 
#define ovs_mutex_lock(mutex) \
69
 
        ovs_mutex_lock_at(mutex, SOURCE_LOCATOR)
70
 
 
71
 
int ovs_mutex_trylock_at(const struct ovs_mutex *mutex, const char *where)
72
 
    OVS_TRY_LOCK(0, mutex);
73
 
#define ovs_mutex_trylock(mutex) \
74
 
        ovs_mutex_trylock_at(mutex, SOURCE_LOCATOR)
75
 
 
76
 
void ovs_mutex_cond_wait(pthread_cond_t *, const struct ovs_mutex *);
77
 
 
78
36
/* Wrappers for pthread_mutex_*() that abort the process on any error.
79
37
 * This is still needed when ovs-atomic-pthreads.h is used. */
80
38
void xpthread_mutex_lock(pthread_mutex_t *mutex);
130
88
void ovs_rwlock_wrlock_at(const struct ovs_rwlock *rwlock, const char *where)
131
89
    OVS_ACQ_WRLOCK(rwlock);
132
90
#define ovs_rwlock_wrlock(rwlock) \
133
 
        ovs_rwlock_wrlock_at(rwlock, SOURCE_LOCATOR)
 
91
        ovs_rwlock_wrlock_at(rwlock, OVS_SOURCE_LOCATOR)
134
92
 
135
93
int ovs_rwlock_trywrlock_at(const struct ovs_rwlock *rwlock, const char *where)
136
94
    OVS_TRY_WRLOCK(0, rwlock);
137
95
#define ovs_rwlock_trywrlock(rwlock) \
138
 
    ovs_rwlock_trywrlock_at(rwlock, SOURCE_LOCATOR)
 
96
    ovs_rwlock_trywrlock_at(rwlock, OVS_SOURCE_LOCATOR)
139
97
 
140
98
void ovs_rwlock_rdlock_at(const struct ovs_rwlock *rwlock, const char *where)
141
99
    OVS_ACQ_RDLOCK(rwlock);
142
100
#define ovs_rwlock_rdlock(rwlock) \
143
 
        ovs_rwlock_rdlock_at(rwlock, SOURCE_LOCATOR)
 
101
        ovs_rwlock_rdlock_at(rwlock, OVS_SOURCE_LOCATOR)
144
102
 
145
103
int ovs_rwlock_tryrdlock_at(const struct ovs_rwlock *rwlock, const char *where)
146
104
    OVS_TRY_RDLOCK(0, rwlock);
147
105
#define ovs_rwlock_tryrdlock(rwlock) \
148
 
        ovs_rwlock_tryrdlock_at(rwlock, SOURCE_LOCATOR)
 
106
        ovs_rwlock_tryrdlock_at(rwlock, OVS_SOURCE_LOCATOR)
149
107
 
150
108
/* ovs_barrier functions analogous to pthread_barrier_*() functions. */
151
109
void ovs_barrier_init(struct ovs_barrier *, uint32_t count);
164
122
void xpthread_key_delete(pthread_key_t);
165
123
void xpthread_setspecific(pthread_key_t, const void *);
166
124
 
 
125
#ifndef _WIN32
 
126
void xpthread_sigmask(int, const sigset_t *, sigset_t *);
 
127
#endif
 
128
 
167
129
pthread_t ovs_thread_create(const char *name, void *(*)(void *), void *);
168
130
void xpthread_join(pthread_t, void **);
169
131
 
496
458
void ovsthread_setspecific(ovsthread_key_t, const void *);
497
459
void *ovsthread_getspecific(ovsthread_key_t);
498
460
 
499
 
/* Convenient once-only execution.
500
 
 *
501
 
 *
502
 
 * Problem
503
 
 * =======
504
 
 *
505
 
 * POSIX provides pthread_once_t and pthread_once() as primitives for running a
506
 
 * set of code only once per process execution.  They are used like this:
507
 
 *
508
 
 *     static void run_once(void) { ...initialization... }
509
 
 *     static pthread_once_t once = PTHREAD_ONCE_INIT;
510
 
 * ...
511
 
 *     pthread_once(&once, run_once);
512
 
 *
513
 
 * pthread_once() does not allow passing any parameters to the initialization
514
 
 * function, which is often inconvenient, because it means that the function
515
 
 * can only access data declared at file scope.
516
 
 *
517
 
 *
518
 
 * Solution
519
 
 * ========
520
 
 *
521
 
 * Use ovsthread_once, like this, instead:
522
 
 *
523
 
 *     static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
524
 
 *
525
 
 *     if (ovsthread_once_start(&once)) {
526
 
 *         ...initialization...
527
 
 *         ovsthread_once_done(&once);
528
 
 *     }
529
 
 */
530
 
 
531
 
struct ovsthread_once {
532
 
    atomic_bool done;
533
 
    struct ovs_mutex mutex;
534
 
};
535
 
 
536
 
#define OVSTHREAD_ONCE_INITIALIZER              \
537
 
    {                                           \
538
 
        ATOMIC_VAR_INIT(false),                 \
539
 
        OVS_MUTEX_INITIALIZER,                  \
540
 
    }
541
 
 
542
 
static inline bool ovsthread_once_start(struct ovsthread_once *once)
543
 
    OVS_TRY_LOCK(true, once->mutex);
544
 
void ovsthread_once_done(struct ovsthread_once *once)
545
 
    OVS_RELEASES(once->mutex);
546
 
 
547
 
bool ovsthread_once_start__(struct ovsthread_once *once)
548
 
    OVS_TRY_LOCK(false, once->mutex);
549
 
 
550
 
static inline bool
551
 
ovsthread_once_is_done__(struct ovsthread_once *once)
552
 
{
553
 
    bool done;
554
 
 
555
 
    atomic_read_explicit(&once->done, &done, memory_order_relaxed);
556
 
    return done;
557
 
}
558
 
 
559
 
/* Returns true if this is the first call to ovsthread_once_start() for
560
 
 * 'once'.  In this case, the caller should perform whatever initialization
561
 
 * actions it needs to do, then call ovsthread_once_done() for 'once'.
562
 
 *
563
 
 * Returns false if this is not the first call to ovsthread_once_start() for
564
 
 * 'once'.  In this case, the call will not return until after
565
 
 * ovsthread_once_done() has been called. */
566
 
static inline bool
567
 
ovsthread_once_start(struct ovsthread_once *once)
568
 
{
569
 
    return OVS_UNLIKELY(!ovsthread_once_is_done__(once)
570
 
                        && !ovsthread_once_start__(once));
571
 
}
572
 
 
573
461
/* Thread ID.
574
462
 *
575
463
 * pthread_t isn't so nice for some purposes.  Its size and representation are
622
510
bool single_threaded(void);
623
511
 
624
512
void assert_single_threaded_at(const char *where);
625
 
#define assert_single_threaded() assert_single_threaded_at(SOURCE_LOCATOR)
 
513
#define assert_single_threaded() assert_single_threaded_at(OVS_SOURCE_LOCATOR)
626
514
 
627
515
#ifndef _WIN32
628
516
pid_t xfork_at(const char *where);
629
 
#define xfork() xfork_at(SOURCE_LOCATOR)
 
517
#define xfork() xfork_at(OVS_SOURCE_LOCATOR)
630
518
#endif
631
519
 
632
520
void forbid_forking(const char *reason);