Coverage Report

Created: 2026-08-31 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openvswitch/lib/ovs-thread.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2013, 2014 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 "ovs-rcu.h"
25
#include "openvswitch/thread.h"
26
#include "util.h"
27
28
struct seq;
29
30
/* Poll-block()-able barrier similar to pthread_barrier_t. */
31
struct ovs_barrier_impl;
32
struct ovs_barrier {
33
    OVSRCU_TYPE(struct ovs_barrier_impl *) impl;
34
};
35
36
/* Wrappers for pthread_mutexattr_*() that abort the process on any error. */
37
void xpthread_mutexattr_init(pthread_mutexattr_t *);
38
void xpthread_mutexattr_destroy(pthread_mutexattr_t *);
39
void xpthread_mutexattr_settype(pthread_mutexattr_t *, int type);
40
void xpthread_mutexattr_gettype(pthread_mutexattr_t *, int *typep);
41
42
/* Read-write lock.
43
 *
44
 * An ovs_rwlock does not support recursive readers, because POSIX allows
45
 * taking the reader lock recursively to deadlock when a thread is waiting on
46
 * the write-lock.  (NetBSD does deadlock.)  glibc rwlocks in their default
47
 * configuration do not deadlock, but ovs_rwlock_init() initializes rwlocks as
48
 * non-recursive (which will deadlock) for two reasons:
49
 *
50
 *     - glibc only provides fairness to writers in this mode.
51
 *
52
 *     - It's better to find bugs in the primary Open vSwitch target rather
53
 *       than exposing them only to porters. */
54
struct OVS_LOCKABLE ovs_rwlock {
55
    pthread_rwlock_t lock;
56
    const char *where;          /* NULL if and only if uninitialized. */
57
};
58
59
/* Initializer. */
60
#ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
61
#define OVS_RWLOCK_INITIALIZER \
62
        { PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, "<unlocked>" }
63
#else
64
#define OVS_RWLOCK_INITIALIZER { PTHREAD_RWLOCK_INITIALIZER, "<unlocked>" }
65
#endif
66
67
/* ovs_rwlock functions analogous to pthread_rwlock_*() functions.
68
 *
69
 * Most of these functions abort the process with an error message on any
70
 * error.  The "trylock" functions are exception: they pass through a 0 or
71
 * EBUSY return value to the caller and abort on any other error. */
72
void ovs_rwlock_init(struct ovs_rwlock *);
73
void ovs_rwlock_destroy(struct ovs_rwlock *);
74
void ovs_rwlock_unlock(const struct ovs_rwlock *rwlock) OVS_RELEASES(rwlock);
75
76
/* Wrappers for pthread_rwlockattr_*() that abort the process on any error. */
77
void xpthread_rwlockattr_init(pthread_rwlockattr_t *);
78
void xpthread_rwlockattr_destroy(pthread_rwlockattr_t *);
79
#ifdef PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP
80
void xpthread_rwlockattr_setkind_np(pthread_rwlockattr_t *, int kind);
81
#endif
82
83
void ovs_rwlock_wrlock_at(const struct ovs_rwlock *rwlock, const char *where)
84
    OVS_ACQ_WRLOCK(rwlock);
85
#define ovs_rwlock_wrlock(rwlock) \
86
0
        ovs_rwlock_wrlock_at(rwlock, OVS_SOURCE_LOCATOR)
87
88
int ovs_rwlock_trywrlock_at(const struct ovs_rwlock *rwlock, const char *where)
89
    OVS_TRY_WRLOCK(0, rwlock);
90
#define ovs_rwlock_trywrlock(rwlock) \
91
    ovs_rwlock_trywrlock_at(rwlock, OVS_SOURCE_LOCATOR)
92
93
void ovs_rwlock_rdlock_at(const struct ovs_rwlock *rwlock, const char *where)
94
    OVS_ACQ_RDLOCK(rwlock);
95
#define ovs_rwlock_rdlock(rwlock) \
96
0
        ovs_rwlock_rdlock_at(rwlock, OVS_SOURCE_LOCATOR)
97
98
int ovs_rwlock_tryrdlock_at(const struct ovs_rwlock *rwlock, const char *where)
99
    OVS_TRY_RDLOCK(0, rwlock);
100
#define ovs_rwlock_tryrdlock(rwlock) \
101
        ovs_rwlock_tryrdlock_at(rwlock, OVS_SOURCE_LOCATOR)
102
103
/* ovs_barrier functions analogous to pthread_barrier_*() functions. */
104
void ovs_barrier_init(struct ovs_barrier *, uint32_t count);
105
void ovs_barrier_destroy(struct ovs_barrier *);
106
void ovs_barrier_block(struct ovs_barrier *);
107
108
/* Wrappers for xpthread_cond_*() that abort the process on any error.
109
 *
110
 * Use ovs_mutex_cond_wait() to wait for a condition. */
111
void xpthread_cond_init(pthread_cond_t *, pthread_condattr_t *);
112
void xpthread_cond_destroy(pthread_cond_t *);
113
void xpthread_cond_signal(pthread_cond_t *);
114
void xpthread_cond_broadcast(pthread_cond_t *);
115
116
void xpthread_key_create(pthread_key_t *, void (*destructor)(void *));
117
void xpthread_key_delete(pthread_key_t);
118
void xpthread_setspecific(pthread_key_t, const void *);
119
120
void xpthread_sigmask(int, const sigset_t *, sigset_t *);
121
122
pthread_t ovs_thread_create(const char *name, void *(*)(void *), void *);
123
void xpthread_join(pthread_t, void **);
124

125
/* Per-thread data.
126
 *
127
 *
128
 * Standard Forms
129
 * ==============
130
 *
131
 * Multiple forms of standard per-thread data exist, each with its own pluses
132
 * and minuses.  In general, if one of these forms is appropriate, then it's a
133
 * good idea to use it:
134
 *
135
 *     - POSIX per-thread data via pthread_key_t is portable to any pthreads
136
 *       implementation, and allows a destructor function to be defined.  It
137
 *       only (directly) supports per-thread pointers, which are always
138
 *       initialized to NULL.  It requires once-only allocation of a
139
 *       pthread_key_t value.  It is relatively slow.  Typically few
140
 *       "pthread_key_t"s are available (POSIX requires only at least 128,
141
 *       glibc supplies only 1024).
142
 *
143
 *     - The thread_local feature newly defined in C11 <threads.h> works with
144
 *       any data type and initializer, and it is fast.  thread_local does not
145
 *       require once-only initialization like pthread_key_t.  C11 does not
146
 *       define what happens if one attempts to access a thread_local object
147
 *       from a thread other than the one to which that object belongs.  There
148
 *       is no provision to call a user-specified destructor when a thread
149
 *       ends.  Typical implementations allow for an arbitrary amount of
150
 *       thread_local storage, but statically allocated only.
151
 *
152
 *     - The __thread keyword is a GCC extension similar to thread_local but
153
 *       with a longer history.  __thread is not portable to every GCC version
154
 *       or environment.  __thread does not restrict the use of a thread-local
155
 *       object outside its own thread.
156
 *
157
 * Here's a handy summary:
158
 *
159
 *                     pthread_key_t     thread_local       __thread
160
 *                     -------------     ------------     -------------
161
 * portability             high               low             medium
162
 * speed                    low              high               high
163
 * supports destructors?    yes                no                 no
164
 * needs key allocation?    yes                no                 no
165
 * arbitrary initializer?    no               yes                yes
166
 * cross-thread access?     yes                no                yes
167
 * amount available?        few            arbitrary         arbitrary
168
 * dynamically allocated?   yes                no                 no
169
 *
170
 *
171
 * Extensions
172
 * ==========
173
 *
174
 * OVS provides some extensions and wrappers:
175
 *
176
 *     - In a situation where the performance of thread_local or __thread is
177
 *       desirable, but portability is required, DEFINE_STATIC_PER_THREAD_DATA
178
 *       and DECLARE_EXTERN_PER_THREAD_DATA/DEFINE_EXTERN_PER_THREAD_DATA may
179
 *       be appropriate (see below).
180
 *
181
 *     - DEFINE_PER_THREAD_MALLOCED_DATA can be convenient for simple
182
 *       per-thread malloc()'d buffers.
183
 *
184
 *     - struct ovs_tsd provides an alternative to pthread_key_t that isn't
185
 *       limited to a small number of keys.
186
 */
187
188
/* For static data, use this macro in a source file:
189
 *
190
 *    DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, INITIALIZER).
191
 *
192
 * For global data, "declare" the data in the header and "define" it in
193
 * the source file, with:
194
 *
195
 *    DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME).
196
 *    DEFINE_EXTERN_PER_THREAD_DATA(NAME, INITIALIZER).
197
 *
198
 * One should prefer to use POSIX per-thread data, via pthread_key_t, when its
199
 * performance is acceptable, because of its portability (see the table above).
200
 * This macro is an alternatives that takes advantage of thread_local (and
201
 * __thread), for its performance, when it is available, and falls back to
202
 * POSIX per-thread data otherwise.
203
 *
204
 * Defines per-thread variable NAME with the given TYPE, initialized to
205
 * INITIALIZER (which must be valid as an initializer for a variable with
206
 * static lifetime).
207
 *
208
 * The public interface to the variable is:
209
 *
210
 *    TYPE *NAME_get(void)
211
 *    TYPE *NAME_get_unsafe(void)
212
 *
213
 *       Returns the address of this thread's instance of NAME.
214
 *
215
 *       Use NAME_get() in a context where this might be the first use of the
216
 *       per-thread variable in the program.  Use NAME_get_unsafe(), which
217
 *       avoids a conditional test and is thus slightly faster, in a context
218
 *       where one knows that NAME_get() has already been called previously.
219
 *
220
 * There is no "NAME_set()" (or "NAME_set_unsafe()") function.  To set the
221
 * value of the per-thread variable, dereference the pointer returned by
222
 * TYPE_get() or TYPE_get_unsafe(), e.g. *TYPE_get() = 0.
223
 */
224
#if HAVE_THREAD_LOCAL || HAVE___THREAD
225
226
#if HAVE_THREAD_LOCAL
227
#include <threads.h>
228
#elif HAVE___THREAD
229
#define thread_local __thread
230
#else
231
#error
232
#endif
233
234
#define DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, ...)                  \
235
    typedef TYPE NAME##_type;                                           \
236
                                                                        \
237
    static NAME##_type *                                                \
238
    NAME##_get_unsafe(void)                                             \
239
700k
    {                                                                   \
240
700k
        static thread_local NAME##_type var = __VA_ARGS__;              \
241
700k
        return &var;                                                    \
242
700k
    }                                                                   \
Unexecuted instantiation: poll-loop.c:counter_poll_create_node_get_unsafe
Unexecuted instantiation: poll-loop.c:counter_poll_zero_timeout_get_unsafe
Unexecuted instantiation: seq.c:counter_seq_change_get_unsafe
Unexecuted instantiation: timeval.c:counter_long_poll_interval_get_unsafe
Unexecuted instantiation: timeval.c:last_wakeup_get_unsafe
Unexecuted instantiation: timeval.c:last_seq_get_unsafe
Unexecuted instantiation: unixctl.c:counter_unixctl_received_get_unsafe
Unexecuted instantiation: unixctl.c:counter_unixctl_replied_get_unsafe
util.c:counter_util_xalloc_get_unsafe
Line
Count
Source
239
689k
    {                                                                   \
240
689k
        static thread_local NAME##_type var = __VA_ARGS__;              \
241
689k
        return &var;                                                    \
242
689k
    }                                                                   \
Unexecuted instantiation: util.c:strerror_buffer_get_unsafe
Unexecuted instantiation: vlog.c:msg_num_get_unsafe
Unexecuted instantiation: coverage.c:coverage_clear_time_get_unsafe
Unexecuted instantiation: dp-packet.c:counter_dp_packet_batch_grow_get_unsafe
Unexecuted instantiation: dp-packet-gso.c:counter_dp_packet_gso_get_unsafe
Unexecuted instantiation: dp-packet-gso.c:counter_dp_packet_partial_gso_get_unsafe
Unexecuted instantiation: flow.c:counter_flow_extract_get_unsafe
Unexecuted instantiation: flow.c:counter_miniflow_extract_ipv4_pkt_len_error_get_unsafe
Unexecuted instantiation: flow.c:counter_miniflow_extract_ipv4_pkt_too_short_get_unsafe
Unexecuted instantiation: flow.c:counter_miniflow_extract_ipv6_pkt_len_error_get_unsafe
Unexecuted instantiation: flow.c:counter_miniflow_extract_ipv6_pkt_too_short_get_unsafe
flow.c:counter_miniflow_malloc_get_unsafe
Line
Count
Source
239
11.1k
    {                                                                   \
240
11.1k
        static thread_local NAME##_type var = __VA_ARGS__;              \
241
11.1k
        return &var;                                                    \
242
11.1k
    }                                                                   \
hmap.c:counter_hmap_pathological_get_unsafe
Line
Count
Source
239
11
    {                                                                   \
240
11
        static thread_local NAME##_type var = __VA_ARGS__;              \
241
11
        return &var;                                                    \
242
11
    }                                                                   \
hmap.c:counter_hmap_expand_get_unsafe
Line
Count
Source
239
34
    {                                                                   \
240
34
        static thread_local NAME##_type var = __VA_ARGS__;              \
241
34
        return &var;                                                    \
242
34
    }                                                                   \
Unexecuted instantiation: hmap.c:counter_hmap_shrink_get_unsafe
Unexecuted instantiation: hmap.c:counter_hmap_reserve_get_unsafe
Unexecuted instantiation: jsonrpc.c:counter_jsonrpc_recv_incomplete_get_unsafe
Unexecuted instantiation: netdev.c:counter_netdev_received_get_unsafe
Unexecuted instantiation: netdev.c:counter_netdev_sent_get_unsafe
Unexecuted instantiation: netdev.c:counter_netdev_add_router_get_unsafe
Unexecuted instantiation: netdev.c:counter_netdev_get_stats_get_unsafe
Unexecuted instantiation: netdev.c:counter_netdev_push_header_drops_get_unsafe
Unexecuted instantiation: random.c:seed_get_unsafe
Unexecuted instantiation: stream.c:counter_pstream_open_get_unsafe
Unexecuted instantiation: stream.c:counter_stream_open_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_set_policing_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_arp_lookup_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_get_ifindex_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_get_hwaddr_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_set_hwaddr_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_get_ethtool_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_set_ethtool_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_linux_invalid_l4_csum_get_unsafe
Unexecuted instantiation: netdev-linux.c:counter_netdev_linux_unknown_l4_csum_get_unsafe
Unexecuted instantiation: netlink-socket.c:counter_netlink_overflow_get_unsafe
Unexecuted instantiation: netlink-socket.c:counter_netlink_received_get_unsafe
Unexecuted instantiation: netlink-socket.c:counter_netlink_recv_jumbo_get_unsafe
Unexecuted instantiation: netlink-socket.c:counter_netlink_sent_get_unsafe
Unexecuted instantiation: route-table.c:counter_route_table_dump_get_unsafe
Unexecuted instantiation: tc.c:counter_tc_netlink_malformed_reply_get_unsafe
Unexecuted instantiation: ccmap.c:counter_ccmap_expand_get_unsafe
Unexecuted instantiation: ccmap.c:counter_ccmap_shrink_get_unsafe
Unexecuted instantiation: cmap.c:counter_cmap_expand_get_unsafe
Unexecuted instantiation: cmap.c:counter_cmap_shrink_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_destroy_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_execute_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_execute_error_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_execute_with_help_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_flow_del_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_flow_del_error_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_flow_flush_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_flow_get_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_flow_get_error_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_flow_put_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_flow_put_error_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_meter_del_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_meter_get_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_meter_set_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_port_add_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_port_del_get_unsafe
Unexecuted instantiation: dpif.c:counter_dpif_purge_get_unsafe
Unexecuted instantiation: lockfile.c:counter_lockfile_lock_get_unsafe
Unexecuted instantiation: lockfile.c:counter_lockfile_error_get_unsafe
Unexecuted instantiation: lockfile.c:counter_lockfile_unlock_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_datapath_drop_sample_error_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_datapath_drop_nsh_decap_error_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_of_pipeline_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_bridge_not_found_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_recursion_too_deep_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_too_many_resubmit_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_stack_too_deep_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_no_recirculation_context_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_recirculation_conflict_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_too_many_mpls_labels_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_invalid_tunnel_metadata_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_unsupported_packet_type_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_congestion_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_forwarding_disabled_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_tunnel_routing_failed_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_tunnel_output_no_ethernet_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_tunnel_neigh_cache_miss_get_unsafe
Unexecuted instantiation: odp-execute.c:counter_drop_action_tunnel_header_build_failed_get_unsafe
Unexecuted instantiation: process.c:counter_process_start_get_unsafe
Unexecuted instantiation: netdev-native-tnl.c:counter_native_tnl_l3csum_checked_get_unsafe
Unexecuted instantiation: netdev-native-tnl.c:counter_native_tnl_l3csum_err_get_unsafe
Unexecuted instantiation: netdev-native-tnl.c:counter_native_tnl_l4csum_checked_get_unsafe
Unexecuted instantiation: netdev-native-tnl.c:counter_native_tnl_l4csum_err_get_unsafe
Unexecuted instantiation: netlink-notifier.c:counter_nln_changed_get_unsafe
Unexecuted instantiation: conntrack.c:counter_conntrack_full_get_unsafe
Unexecuted instantiation: conntrack.c:counter_conntrack_l3csum_checked_get_unsafe
Unexecuted instantiation: conntrack.c:counter_conntrack_l3csum_err_get_unsafe
Unexecuted instantiation: conntrack.c:counter_conntrack_l4csum_checked_get_unsafe
Unexecuted instantiation: conntrack.c:counter_conntrack_l4csum_err_get_unsafe
Unexecuted instantiation: conntrack.c:counter_conntrack_lookup_natted_miss_get_unsafe
Unexecuted instantiation: conntrack.c:counter_conntrack_zone_full_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_meter_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_upcall_error_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_lock_error_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_userspace_action_error_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_tunnel_push_error_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_tunnel_pop_error_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_recirc_error_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_invalid_port_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_invalid_bond_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_invalid_tnl_port_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_rx_invalid_packet_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_hw_post_process_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_hw_post_process_consumed_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_dpif_netdev_output_grow_queues_get_unsafe
Unexecuted instantiation: dpif-netdev.c:counter_dpif_netdev_recirc_big_batch_get_unsafe
Unexecuted instantiation: dpif-netdev.c:recirc_depth_get_unsafe
Unexecuted instantiation: hindex.c:counter_hindex_pathological_get_unsafe
Unexecuted instantiation: hindex.c:counter_hindex_expand_get_unsafe
Unexecuted instantiation: hindex.c:counter_hindex_shrink_get_unsafe
Unexecuted instantiation: hindex.c:counter_hindex_reserve_get_unsafe
Unexecuted instantiation: ipf.c:counter_ipf_stuck_frag_list_expired_get_unsafe
Unexecuted instantiation: ipf.c:counter_ipf_stuck_frag_list_purged_get_unsafe
Unexecuted instantiation: ipf.c:counter_ipf_l3csum_checked_get_unsafe
Unexecuted instantiation: ipf.c:counter_ipf_l3csum_err_get_unsafe
Unexecuted instantiation: conntrack-tcp.c:counter_conntrack_tcp_seq_chk_bypass_get_unsafe
Unexecuted instantiation: conntrack-tcp.c:counter_conntrack_tcp_seq_chk_failed_get_unsafe
Unexecuted instantiation: conntrack-tcp.c:counter_conntrack_invalid_tcp_flags_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:counter_txn_uncommitted_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:counter_txn_unchanged_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:counter_txn_incomplete_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:counter_txn_aborted_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:counter_txn_success_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:counter_txn_try_again_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:counter_txn_not_locked_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:counter_txn_error_get_unsafe
243
                                                                        \
244
    static NAME##_type *                                                \
245
    NAME##_get(void)                                                    \
246
700k
    {                                                                   \
247
700k
        return NAME##_get_unsafe();                                     \
248
700k
    }
Unexecuted instantiation: poll-loop.c:counter_poll_create_node_get
Unexecuted instantiation: poll-loop.c:counter_poll_zero_timeout_get
Unexecuted instantiation: seq.c:counter_seq_change_get
Unexecuted instantiation: timeval.c:counter_long_poll_interval_get
Unexecuted instantiation: timeval.c:last_wakeup_get
Unexecuted instantiation: timeval.c:last_seq_get
Unexecuted instantiation: unixctl.c:counter_unixctl_received_get
Unexecuted instantiation: unixctl.c:counter_unixctl_replied_get
util.c:counter_util_xalloc_get
Line
Count
Source
246
689k
    {                                                                   \
247
689k
        return NAME##_get_unsafe();                                     \
248
689k
    }
Unexecuted instantiation: util.c:strerror_buffer_get
Unexecuted instantiation: vlog.c:msg_num_get
Unexecuted instantiation: coverage.c:coverage_clear_time_get
Unexecuted instantiation: dp-packet.c:counter_dp_packet_batch_grow_get
Unexecuted instantiation: dp-packet-gso.c:counter_dp_packet_gso_get
Unexecuted instantiation: dp-packet-gso.c:counter_dp_packet_partial_gso_get
Unexecuted instantiation: flow.c:counter_flow_extract_get
Unexecuted instantiation: flow.c:counter_miniflow_extract_ipv4_pkt_len_error_get
Unexecuted instantiation: flow.c:counter_miniflow_extract_ipv4_pkt_too_short_get
Unexecuted instantiation: flow.c:counter_miniflow_extract_ipv6_pkt_len_error_get
Unexecuted instantiation: flow.c:counter_miniflow_extract_ipv6_pkt_too_short_get
flow.c:counter_miniflow_malloc_get
Line
Count
Source
246
11.1k
    {                                                                   \
247
11.1k
        return NAME##_get_unsafe();                                     \
248
11.1k
    }
hmap.c:counter_hmap_pathological_get
Line
Count
Source
246
11
    {                                                                   \
247
11
        return NAME##_get_unsafe();                                     \
248
11
    }
hmap.c:counter_hmap_expand_get
Line
Count
Source
246
34
    {                                                                   \
247
34
        return NAME##_get_unsafe();                                     \
248
34
    }
Unexecuted instantiation: hmap.c:counter_hmap_shrink_get
Unexecuted instantiation: hmap.c:counter_hmap_reserve_get
Unexecuted instantiation: jsonrpc.c:counter_jsonrpc_recv_incomplete_get
Unexecuted instantiation: netdev.c:counter_netdev_received_get
Unexecuted instantiation: netdev.c:counter_netdev_sent_get
Unexecuted instantiation: netdev.c:counter_netdev_add_router_get
Unexecuted instantiation: netdev.c:counter_netdev_get_stats_get
Unexecuted instantiation: netdev.c:counter_netdev_push_header_drops_get
Unexecuted instantiation: random.c:seed_get
Unexecuted instantiation: stream.c:counter_pstream_open_get
Unexecuted instantiation: stream.c:counter_stream_open_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_set_policing_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_arp_lookup_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_get_ifindex_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_get_hwaddr_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_set_hwaddr_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_get_ethtool_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_set_ethtool_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_linux_invalid_l4_csum_get
Unexecuted instantiation: netdev-linux.c:counter_netdev_linux_unknown_l4_csum_get
Unexecuted instantiation: netlink-socket.c:counter_netlink_overflow_get
Unexecuted instantiation: netlink-socket.c:counter_netlink_received_get
Unexecuted instantiation: netlink-socket.c:counter_netlink_recv_jumbo_get
Unexecuted instantiation: netlink-socket.c:counter_netlink_sent_get
Unexecuted instantiation: route-table.c:counter_route_table_dump_get
Unexecuted instantiation: tc.c:counter_tc_netlink_malformed_reply_get
Unexecuted instantiation: ccmap.c:counter_ccmap_expand_get
Unexecuted instantiation: ccmap.c:counter_ccmap_shrink_get
Unexecuted instantiation: cmap.c:counter_cmap_expand_get
Unexecuted instantiation: cmap.c:counter_cmap_shrink_get
Unexecuted instantiation: dpif.c:counter_dpif_destroy_get
Unexecuted instantiation: dpif.c:counter_dpif_execute_get
Unexecuted instantiation: dpif.c:counter_dpif_execute_error_get
Unexecuted instantiation: dpif.c:counter_dpif_execute_with_help_get
Unexecuted instantiation: dpif.c:counter_dpif_flow_del_get
Unexecuted instantiation: dpif.c:counter_dpif_flow_del_error_get
Unexecuted instantiation: dpif.c:counter_dpif_flow_flush_get
Unexecuted instantiation: dpif.c:counter_dpif_flow_get_get
Unexecuted instantiation: dpif.c:counter_dpif_flow_get_error_get
Unexecuted instantiation: dpif.c:counter_dpif_flow_put_get
Unexecuted instantiation: dpif.c:counter_dpif_flow_put_error_get
Unexecuted instantiation: dpif.c:counter_dpif_meter_del_get
Unexecuted instantiation: dpif.c:counter_dpif_meter_get_get
Unexecuted instantiation: dpif.c:counter_dpif_meter_set_get
Unexecuted instantiation: dpif.c:counter_dpif_port_add_get
Unexecuted instantiation: dpif.c:counter_dpif_port_del_get
Unexecuted instantiation: dpif.c:counter_dpif_purge_get
Unexecuted instantiation: lockfile.c:counter_lockfile_lock_get
Unexecuted instantiation: lockfile.c:counter_lockfile_error_get
Unexecuted instantiation: lockfile.c:counter_lockfile_unlock_get
Unexecuted instantiation: odp-execute.c:counter_datapath_drop_sample_error_get
Unexecuted instantiation: odp-execute.c:counter_datapath_drop_nsh_decap_error_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_of_pipeline_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_bridge_not_found_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_recursion_too_deep_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_too_many_resubmit_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_stack_too_deep_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_no_recirculation_context_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_recirculation_conflict_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_too_many_mpls_labels_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_invalid_tunnel_metadata_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_unsupported_packet_type_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_congestion_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_forwarding_disabled_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_tunnel_routing_failed_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_tunnel_output_no_ethernet_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_tunnel_neigh_cache_miss_get
Unexecuted instantiation: odp-execute.c:counter_drop_action_tunnel_header_build_failed_get
Unexecuted instantiation: process.c:counter_process_start_get
Unexecuted instantiation: netdev-native-tnl.c:counter_native_tnl_l3csum_checked_get
Unexecuted instantiation: netdev-native-tnl.c:counter_native_tnl_l3csum_err_get
Unexecuted instantiation: netdev-native-tnl.c:counter_native_tnl_l4csum_checked_get
Unexecuted instantiation: netdev-native-tnl.c:counter_native_tnl_l4csum_err_get
Unexecuted instantiation: netlink-notifier.c:counter_nln_changed_get
Unexecuted instantiation: conntrack.c:counter_conntrack_full_get
Unexecuted instantiation: conntrack.c:counter_conntrack_l3csum_checked_get
Unexecuted instantiation: conntrack.c:counter_conntrack_l3csum_err_get
Unexecuted instantiation: conntrack.c:counter_conntrack_l4csum_checked_get
Unexecuted instantiation: conntrack.c:counter_conntrack_l4csum_err_get
Unexecuted instantiation: conntrack.c:counter_conntrack_lookup_natted_miss_get
Unexecuted instantiation: conntrack.c:counter_conntrack_zone_full_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_meter_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_upcall_error_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_lock_error_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_userspace_action_error_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_tunnel_push_error_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_tunnel_pop_error_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_recirc_error_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_invalid_port_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_invalid_bond_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_invalid_tnl_port_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_rx_invalid_packet_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_hw_post_process_get
Unexecuted instantiation: dpif-netdev.c:counter_datapath_drop_hw_post_process_consumed_get
Unexecuted instantiation: dpif-netdev.c:counter_dpif_netdev_output_grow_queues_get
Unexecuted instantiation: dpif-netdev.c:counter_dpif_netdev_recirc_big_batch_get
Unexecuted instantiation: dpif-netdev.c:recirc_depth_get
Unexecuted instantiation: hindex.c:counter_hindex_pathological_get
Unexecuted instantiation: hindex.c:counter_hindex_expand_get
Unexecuted instantiation: hindex.c:counter_hindex_shrink_get
Unexecuted instantiation: hindex.c:counter_hindex_reserve_get
Unexecuted instantiation: ipf.c:counter_ipf_stuck_frag_list_expired_get
Unexecuted instantiation: ipf.c:counter_ipf_stuck_frag_list_purged_get
Unexecuted instantiation: ipf.c:counter_ipf_l3csum_checked_get
Unexecuted instantiation: ipf.c:counter_ipf_l3csum_err_get
Unexecuted instantiation: conntrack-tcp.c:counter_conntrack_tcp_seq_chk_bypass_get
Unexecuted instantiation: conntrack-tcp.c:counter_conntrack_tcp_seq_chk_failed_get
Unexecuted instantiation: conntrack-tcp.c:counter_conntrack_invalid_tcp_flags_get
Unexecuted instantiation: ovsdb-idl.c:counter_txn_uncommitted_get
Unexecuted instantiation: ovsdb-idl.c:counter_txn_unchanged_get
Unexecuted instantiation: ovsdb-idl.c:counter_txn_incomplete_get
Unexecuted instantiation: ovsdb-idl.c:counter_txn_aborted_get
Unexecuted instantiation: ovsdb-idl.c:counter_txn_success_get
Unexecuted instantiation: ovsdb-idl.c:counter_txn_try_again_get
Unexecuted instantiation: ovsdb-idl.c:counter_txn_not_locked_get
Unexecuted instantiation: ovsdb-idl.c:counter_txn_error_get
249
#define DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME)                      \
250
    typedef TYPE NAME##_type;                                           \
251
    extern thread_local NAME##_type NAME##_var;                         \
252
                                                                        \
253
    static inline NAME##_type *                                         \
254
    NAME##_get_unsafe(void)                                             \
255
0
    {                                                                   \
256
0
        return (NAME##_type *)&NAME##_var;                              \
257
0
    }                                                                   \
Unexecuted instantiation: ofp-msgs.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ovs-thread.c:ovsthread_id_get_unsafe
Unexecuted instantiation: packets.c:ovsthread_id_get_unsafe
Unexecuted instantiation: poll-loop.c:ovsthread_id_get_unsafe
Unexecuted instantiation: seq.c:ovsthread_id_get_unsafe
Unexecuted instantiation: socket-util.c:ovsthread_id_get_unsafe
Unexecuted instantiation: timeval.c:ovsthread_id_get_unsafe
Unexecuted instantiation: unixctl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: util.c:ovsthread_id_get_unsafe
Unexecuted instantiation: vlog.c:ovsthread_id_get_unsafe
Unexecuted instantiation: async-append-aio.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dirs.c:ovsthread_id_get_unsafe
Unexecuted instantiation: command-line.c:ovsthread_id_get_unsafe
Unexecuted instantiation: coverage.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dp-packet.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dp-packet-gso.c:ovsthread_id_get_unsafe
Unexecuted instantiation: fatal-signal.c:ovsthread_id_get_unsafe
Unexecuted instantiation: flow.c:ovsthread_id_get_unsafe
Unexecuted instantiation: hmap.c:ovsthread_id_get_unsafe
Unexecuted instantiation: jsonrpc.c:ovsthread_id_get_unsafe
Unexecuted instantiation: meta-flow.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netlink.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ovs-rcu.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ovs-router.c:ovsthread_id_get_unsafe
Unexecuted instantiation: random.c:ovsthread_id_get_unsafe
Unexecuted instantiation: stream.c:ovsthread_id_get_unsafe
Unexecuted instantiation: tnl-ports.c:ovsthread_id_get_unsafe
Unexecuted instantiation: userspace-tso.c:ovsthread_id_get_unsafe
Unexecuted instantiation: uuid.c:ovsthread_id_get_unsafe
Unexecuted instantiation: daemon-unix.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-linux.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netlink-socket.c:ovsthread_id_get_unsafe
Unexecuted instantiation: route-table.c:ovsthread_id_get_unsafe
Unexecuted instantiation: tc.c:ovsthread_id_get_unsafe
Unexecuted instantiation: stream-ssl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ccmap.c:ovsthread_id_get_unsafe
Unexecuted instantiation: cmap.c:ovsthread_id_get_unsafe
Unexecuted instantiation: connectivity.c:ovsthread_id_get_unsafe
Unexecuted instantiation: daemon.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-offload.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-offload-dummy.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif.c:ovsthread_id_get_unsafe
Unexecuted instantiation: guarded-list.c:ovsthread_id_get_unsafe
Unexecuted instantiation: lockfile.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-vport.c:ovsthread_id_get_unsafe
Unexecuted instantiation: odp-execute.c:ovsthread_id_get_unsafe
Unexecuted instantiation: odp-util.c:ovsthread_id_get_unsafe
Unexecuted instantiation: process.c:ovsthread_id_get_unsafe
Unexecuted instantiation: tnl-neigh-cache.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-native-tnl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netlink.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netlink-rtnl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-offload-tc.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-offload-tc-netdev.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netlink-conntrack.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netlink-notifier.c:ovsthread_id_get_unsafe
Unexecuted instantiation: conntrack.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ct-dpif.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpctl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netdev.c:ovsthread_id_get_unsafe
Unexecuted instantiation: fat-rwlock.c:ovsthread_id_get_unsafe
Unexecuted instantiation: hindex.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ipf.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ovs-numa.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpdk-stub.c:ovsthread_id_get_unsafe
Unexecuted instantiation: vswitch-idl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: conntrack-icmp.c:ovsthread_id_get_unsafe
Unexecuted instantiation: conntrack-tcp.c:ovsthread_id_get_unsafe
Unexecuted instantiation: conntrack-tp.c:ovsthread_id_get_unsafe
Unexecuted instantiation: conntrack-other.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netdev-dpcls.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netdev-perf.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ovsdb-data.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ovsdb-idl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ovsdb-types.c:ovsthread_id_get_unsafe
258
                                                                        \
259
    static inline NAME##_type *                                         \
260
    NAME##_get(void)                                                    \
261
0
    {                                                                   \
262
0
        return NAME##_get_unsafe();                                     \
263
0
    }
Unexecuted instantiation: ofp-msgs.c:ovsthread_id_get
Unexecuted instantiation: ovs-thread.c:ovsthread_id_get
Unexecuted instantiation: packets.c:ovsthread_id_get
Unexecuted instantiation: poll-loop.c:ovsthread_id_get
Unexecuted instantiation: seq.c:ovsthread_id_get
Unexecuted instantiation: socket-util.c:ovsthread_id_get
Unexecuted instantiation: timeval.c:ovsthread_id_get
Unexecuted instantiation: unixctl.c:ovsthread_id_get
Unexecuted instantiation: util.c:ovsthread_id_get
Unexecuted instantiation: vlog.c:ovsthread_id_get
Unexecuted instantiation: async-append-aio.c:ovsthread_id_get
Unexecuted instantiation: dirs.c:ovsthread_id_get
Unexecuted instantiation: command-line.c:ovsthread_id_get
Unexecuted instantiation: coverage.c:ovsthread_id_get
Unexecuted instantiation: dp-packet.c:ovsthread_id_get
Unexecuted instantiation: dp-packet-gso.c:ovsthread_id_get
Unexecuted instantiation: fatal-signal.c:ovsthread_id_get
Unexecuted instantiation: flow.c:ovsthread_id_get
Unexecuted instantiation: hmap.c:ovsthread_id_get
Unexecuted instantiation: jsonrpc.c:ovsthread_id_get
Unexecuted instantiation: meta-flow.c:ovsthread_id_get
Unexecuted instantiation: netdev.c:ovsthread_id_get
Unexecuted instantiation: netlink.c:ovsthread_id_get
Unexecuted instantiation: ovs-rcu.c:ovsthread_id_get
Unexecuted instantiation: ovs-router.c:ovsthread_id_get
Unexecuted instantiation: random.c:ovsthread_id_get
Unexecuted instantiation: stream.c:ovsthread_id_get
Unexecuted instantiation: tnl-ports.c:ovsthread_id_get
Unexecuted instantiation: userspace-tso.c:ovsthread_id_get
Unexecuted instantiation: uuid.c:ovsthread_id_get
Unexecuted instantiation: daemon-unix.c:ovsthread_id_get
Unexecuted instantiation: netdev-linux.c:ovsthread_id_get
Unexecuted instantiation: netlink-socket.c:ovsthread_id_get
Unexecuted instantiation: route-table.c:ovsthread_id_get
Unexecuted instantiation: tc.c:ovsthread_id_get
Unexecuted instantiation: stream-ssl.c:ovsthread_id_get
Unexecuted instantiation: ccmap.c:ovsthread_id_get
Unexecuted instantiation: cmap.c:ovsthread_id_get
Unexecuted instantiation: connectivity.c:ovsthread_id_get
Unexecuted instantiation: daemon.c:ovsthread_id_get
Unexecuted instantiation: dpif-offload.c:ovsthread_id_get
Unexecuted instantiation: dpif-offload-dummy.c:ovsthread_id_get
Unexecuted instantiation: dpif.c:ovsthread_id_get
Unexecuted instantiation: guarded-list.c:ovsthread_id_get
Unexecuted instantiation: lockfile.c:ovsthread_id_get
Unexecuted instantiation: netdev-vport.c:ovsthread_id_get
Unexecuted instantiation: odp-execute.c:ovsthread_id_get
Unexecuted instantiation: odp-util.c:ovsthread_id_get
Unexecuted instantiation: process.c:ovsthread_id_get
Unexecuted instantiation: tnl-neigh-cache.c:ovsthread_id_get
Unexecuted instantiation: netdev-native-tnl.c:ovsthread_id_get
Unexecuted instantiation: dpif-netlink.c:ovsthread_id_get
Unexecuted instantiation: dpif-netlink-rtnl.c:ovsthread_id_get
Unexecuted instantiation: dpif-offload-tc.c:ovsthread_id_get
Unexecuted instantiation: dpif-offload-tc-netdev.c:ovsthread_id_get
Unexecuted instantiation: netlink-conntrack.c:ovsthread_id_get
Unexecuted instantiation: netlink-notifier.c:ovsthread_id_get
Unexecuted instantiation: conntrack.c:ovsthread_id_get
Unexecuted instantiation: ct-dpif.c:ovsthread_id_get
Unexecuted instantiation: dpctl.c:ovsthread_id_get
Unexecuted instantiation: dpif-netdev.c:ovsthread_id_get
Unexecuted instantiation: fat-rwlock.c:ovsthread_id_get
Unexecuted instantiation: hindex.c:ovsthread_id_get
Unexecuted instantiation: ipf.c:ovsthread_id_get
Unexecuted instantiation: ovs-numa.c:ovsthread_id_get
Unexecuted instantiation: dpdk-stub.c:ovsthread_id_get
Unexecuted instantiation: vswitch-idl.c:ovsthread_id_get
Unexecuted instantiation: conntrack-icmp.c:ovsthread_id_get
Unexecuted instantiation: conntrack-tcp.c:ovsthread_id_get
Unexecuted instantiation: conntrack-tp.c:ovsthread_id_get
Unexecuted instantiation: conntrack-other.c:ovsthread_id_get
Unexecuted instantiation: dpif-netdev-dpcls.c:ovsthread_id_get
Unexecuted instantiation: dpif-netdev-perf.c:ovsthread_id_get
Unexecuted instantiation: ovsdb-data.c:ovsthread_id_get
Unexecuted instantiation: ovsdb-idl.c:ovsthread_id_get
Unexecuted instantiation: ovsdb-types.c:ovsthread_id_get
264
#define DEFINE_EXTERN_PER_THREAD_DATA(NAME, ...)         \
265
    thread_local NAME##_type NAME##_var = __VA_ARGS__;
266
#else  /* no C implementation support for thread-local storage  */
267
#define DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, ...)                  \
268
    typedef TYPE NAME##_type;                                           \
269
    static pthread_key_t NAME##_key;                                    \
270
                                                                        \
271
    static NAME##_type *                                                \
272
    NAME##_get_unsafe(void)                                             \
273
    {                                                                   \
274
        return pthread_getspecific(NAME##_key);                         \
275
    }                                                                   \
276
                                                                        \
277
    static void                                                         \
278
    NAME##_once_init(void)                                              \
279
    {                                                                   \
280
        if (pthread_key_create(&NAME##_key, free)) {                    \
281
            abort();                                                    \
282
        }                                                               \
283
    }                                                                   \
284
                                                                        \
285
    static NAME##_type *                                                \
286
    NAME##_get(void)                                                    \
287
    {                                                                   \
288
        static pthread_once_t once = PTHREAD_ONCE_INIT;                 \
289
        NAME##_type *value;                                             \
290
                                                                        \
291
        pthread_once(&once, NAME##_once_init);                          \
292
        value = NAME##_get_unsafe();                                    \
293
        if (!value) {                                                   \
294
            static const NAME##_type initial_value = __VA_ARGS__;       \
295
                                                                        \
296
            value = xmalloc__(sizeof *value);                           \
297
            *value = initial_value;                                     \
298
            xpthread_setspecific(NAME##_key, value);                    \
299
        }                                                               \
300
        return value;                                                   \
301
    }
302
#define DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME)                      \
303
    typedef TYPE NAME##_type;                                           \
304
    static pthread_key_t NAME##_key;                                    \
305
                                                                        \
306
    static inline NAME##_type *                                         \
307
    NAME##_get_unsafe(void)                                             \
308
    {                                                                   \
309
        return (NAME##_type *)pthread_getspecific(NAME##_key);          \
310
    }                                                                   \
311
                                                                        \
312
    NAME##_type *NAME##_get(void);
313
#define DEFINE_EXTERN_PER_THREAD_DATA(NAME, ...)                        \
314
    static void                                                         \
315
    NAME##_once_init(void)                                              \
316
    {                                                                   \
317
        if (pthread_key_create(&NAME##_key, free)) {                    \
318
            abort();                                                    \
319
        }                                                               \
320
    }                                                                   \
321
                                                                        \
322
    NAME##_type *                                                       \
323
    NAME##_get(void)                                                    \
324
    {                                                                   \
325
        static pthread_once_t once = PTHREAD_ONCE_INIT;                 \
326
        NAME##_type *value;                                             \
327
                                                                        \
328
        pthread_once(&once, NAME##_once_init);                          \
329
        value = NAME##_get_unsafe();                                    \
330
        if (!value) {                                                   \
331
            static const NAME##_type initial_value = __VA_ARGS__;       \
332
                                                                        \
333
            value = xmalloc__(sizeof *value);                           \
334
            *value = initial_value;                                     \
335
            xpthread_setspecific(NAME##_key, value);                    \
336
        }                                                               \
337
        return value;                                                   \
338
    }
339
#endif
340
341
/* DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME).
342
 *
343
 * This is a simple wrapper around POSIX per-thread data primitives.  It
344
 * defines per-thread variable NAME with the given TYPE, which must be a
345
 * pointer type.  In each thread, the per-thread variable is initialized to
346
 * NULL.  When a thread terminates, the variable is freed with free().
347
 *
348
 * The public interface to the variable is:
349
 *
350
 *    TYPE NAME_get(void)
351
 *    TYPE NAME_get_unsafe(void)
352
 *
353
 *       Returns the value of per-thread variable NAME in this thread.
354
 *
355
 *       Use NAME_get() in a context where this might be the first use of the
356
 *       per-thread variable in the program.  Use NAME_get_unsafe(), which
357
 *       avoids a conditional test and is thus slightly faster, in a context
358
 *       where one knows that NAME_get() has already been called previously.
359
 *
360
 *    TYPE NAME_set(TYPE new_value)
361
 *    TYPE NAME_set_unsafe(TYPE new_value)
362
 *
363
 *       Sets the value of per-thread variable NAME to 'new_value' in this
364
 *       thread, and returns its previous value.
365
 *
366
 *       Use NAME_set() in a context where this might be the first use of the
367
 *       per-thread variable in the program.  Use NAME_set_unsafe(), which
368
 *       avoids a conditional test and is thus slightly faster, in a context
369
 *       where one knows that NAME_set() has already been called previously.
370
 */
371
#define DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME)     \
372
    static pthread_key_t NAME##_key;                    \
373
                                                        \
374
    static void                                         \
375
    NAME##_once_init(void)                              \
376
0
    {                                                   \
377
0
        if (pthread_key_create(&NAME##_key, free)) {    \
378
0
            abort();                                    \
379
0
        }                                               \
380
0
    }                                                   \
Unexecuted instantiation: timeval.c:cpu_tracker_var_once_init
Unexecuted instantiation: util.c:subprogram_name_once_init
Unexecuted instantiation: dpif-netdev-dpcls.c:block_array_once_init
381
                                                        \
382
    static void                                         \
383
    NAME##_init(void)                                   \
384
0
    {                                                   \
385
0
        static pthread_once_t once = PTHREAD_ONCE_INIT; \
386
0
        pthread_once(&once, NAME##_once_init);          \
387
0
    }                                                   \
388
                                                        \
389
    static TYPE                                         \
390
    NAME##_get_unsafe(void)                             \
391
0
    {                                                   \
392
0
        return pthread_getspecific(NAME##_key);         \
393
0
    }                                                   \
Unexecuted instantiation: timeval.c:cpu_tracker_var_get_unsafe
Unexecuted instantiation: util.c:subprogram_name_get_unsafe
Unexecuted instantiation: dpif-netdev-dpcls.c:block_array_get_unsafe
394
                                                        \
395
    static OVS_UNUSED TYPE                              \
396
    NAME##_get(void)                                    \
397
0
    {                                                   \
398
0
        NAME##_init();                                  \
399
0
        return NAME##_get_unsafe();                     \
400
0
    }                                                   \
Unexecuted instantiation: timeval.c:cpu_tracker_var_get
Unexecuted instantiation: util.c:subprogram_name_get
Unexecuted instantiation: dpif-netdev-dpcls.c:block_array_get
401
                                                        \
402
    static TYPE                                         \
403
    NAME##_set_unsafe(TYPE value)                       \
404
0
    {                                                   \
405
0
        TYPE old_value = NAME##_get_unsafe();           \
406
0
        xpthread_setspecific(NAME##_key, value);        \
407
0
        return old_value;                               \
408
0
    }                                                   \
Unexecuted instantiation: timeval.c:cpu_tracker_var_set_unsafe
Unexecuted instantiation: util.c:subprogram_name_set_unsafe
Unexecuted instantiation: dpif-netdev-dpcls.c:block_array_set_unsafe
409
                                                        \
410
    static OVS_UNUSED TYPE                              \
411
    NAME##_set(TYPE value)                              \
412
0
    {                                                   \
413
0
        NAME##_init();                                  \
414
0
        return NAME##_set_unsafe(value);                \
415
0
    }
Unexecuted instantiation: timeval.c:cpu_tracker_var_set
Unexecuted instantiation: util.c:subprogram_name_set
Unexecuted instantiation: dpif-netdev-dpcls.c:block_array_set
416
417
/* Dynamically allocated thread-specific data with lots of slots.
418
 *
419
 * pthread_key_t can provide as few as 128 pieces of thread-specific data (even
420
 * glibc is limited to 1,024).  Thus, one must be careful to allocate only a
421
 * few keys globally.  One cannot, for example, allocate a key for every
422
 * instance of a data structure if there might be an arbitrary number of those
423
 * data structures.
424
 *
425
 * This API is similar to the pthread one (simply search and replace pthread_
426
 * by ovsthread_) but it a much larger limit that can be raised if necessary
427
 * (by recompiling).  Thus, one may more freely use this form of
428
 * thread-specific data.
429
 *
430
 * ovsthread_key_t also differs from pthread_key_t in the following ways:
431
 *
432
 *    - Destructors must not access thread-specific data (via ovsthread_key).
433
 *
434
 *    - The pthread_key_t API allows concurrently exiting threads to start
435
 *      executing the destructor after pthread_key_delete() returns.  The
436
 *      ovsthread_key_t API guarantees that, when ovsthread_key_delete()
437
 *      returns, all destructors have returned and no new ones will start
438
 *      execution.
439
 */
440
typedef struct ovsthread_key *ovsthread_key_t;
441
442
void ovsthread_key_create(ovsthread_key_t *, void (*destructor)(void *));
443
void ovsthread_key_delete(ovsthread_key_t);
444
445
void ovsthread_setspecific(ovsthread_key_t, const void *);
446
void *ovsthread_getspecific(ovsthread_key_t);
447

448
/* Thread ID.
449
 *
450
 * pthread_t isn't so nice for some purposes.  Its size and representation are
451
 * implementation dependent, which means that there is no way to hash it.
452
 * This thread ID avoids the problem.
453
 */
454
455
0
#define OVSTHREAD_ID_UNSET UINT_MAX
456
DECLARE_EXTERN_PER_THREAD_DATA(unsigned int, ovsthread_id);
457
458
/* Initializes the unique per thread identifier */
459
unsigned int ovsthread_id_init(void);
460
461
/* Returns a per-thread identifier unique within the lifetime of the
462
 * process. */
463
static inline unsigned int
464
ovsthread_id_self(void)
465
0
{
466
0
    unsigned int id = *ovsthread_id_get();
467
468
0
    if (OVS_UNLIKELY(id == OVSTHREAD_ID_UNSET)) {
469
0
        id = ovsthread_id_init();
470
0
    }
471
472
0
    return id;
473
0
}
Unexecuted instantiation: ofp-msgs.c:ovsthread_id_self
Unexecuted instantiation: ovs-thread.c:ovsthread_id_self
Unexecuted instantiation: packets.c:ovsthread_id_self
Unexecuted instantiation: poll-loop.c:ovsthread_id_self
Unexecuted instantiation: seq.c:ovsthread_id_self
Unexecuted instantiation: socket-util.c:ovsthread_id_self
Unexecuted instantiation: timeval.c:ovsthread_id_self
Unexecuted instantiation: unixctl.c:ovsthread_id_self
Unexecuted instantiation: util.c:ovsthread_id_self
Unexecuted instantiation: vlog.c:ovsthread_id_self
Unexecuted instantiation: async-append-aio.c:ovsthread_id_self
Unexecuted instantiation: dirs.c:ovsthread_id_self
Unexecuted instantiation: command-line.c:ovsthread_id_self
Unexecuted instantiation: coverage.c:ovsthread_id_self
Unexecuted instantiation: dp-packet.c:ovsthread_id_self
Unexecuted instantiation: dp-packet-gso.c:ovsthread_id_self
Unexecuted instantiation: fatal-signal.c:ovsthread_id_self
Unexecuted instantiation: flow.c:ovsthread_id_self
Unexecuted instantiation: hmap.c:ovsthread_id_self
Unexecuted instantiation: jsonrpc.c:ovsthread_id_self
Unexecuted instantiation: meta-flow.c:ovsthread_id_self
Unexecuted instantiation: netdev.c:ovsthread_id_self
Unexecuted instantiation: netlink.c:ovsthread_id_self
Unexecuted instantiation: ovs-rcu.c:ovsthread_id_self
Unexecuted instantiation: ovs-router.c:ovsthread_id_self
Unexecuted instantiation: random.c:ovsthread_id_self
Unexecuted instantiation: stream.c:ovsthread_id_self
Unexecuted instantiation: tnl-ports.c:ovsthread_id_self
Unexecuted instantiation: userspace-tso.c:ovsthread_id_self
Unexecuted instantiation: uuid.c:ovsthread_id_self
Unexecuted instantiation: daemon-unix.c:ovsthread_id_self
Unexecuted instantiation: netdev-linux.c:ovsthread_id_self
Unexecuted instantiation: netlink-socket.c:ovsthread_id_self
Unexecuted instantiation: route-table.c:ovsthread_id_self
Unexecuted instantiation: tc.c:ovsthread_id_self
Unexecuted instantiation: stream-ssl.c:ovsthread_id_self
Unexecuted instantiation: ccmap.c:ovsthread_id_self
Unexecuted instantiation: cmap.c:ovsthread_id_self
Unexecuted instantiation: connectivity.c:ovsthread_id_self
Unexecuted instantiation: daemon.c:ovsthread_id_self
Unexecuted instantiation: dpif-offload.c:ovsthread_id_self
Unexecuted instantiation: dpif-offload-dummy.c:ovsthread_id_self
Unexecuted instantiation: dpif.c:ovsthread_id_self
Unexecuted instantiation: guarded-list.c:ovsthread_id_self
Unexecuted instantiation: lockfile.c:ovsthread_id_self
Unexecuted instantiation: netdev-vport.c:ovsthread_id_self
Unexecuted instantiation: odp-execute.c:ovsthread_id_self
Unexecuted instantiation: odp-util.c:ovsthread_id_self
Unexecuted instantiation: process.c:ovsthread_id_self
Unexecuted instantiation: tnl-neigh-cache.c:ovsthread_id_self
Unexecuted instantiation: netdev-native-tnl.c:ovsthread_id_self
Unexecuted instantiation: dpif-netlink.c:ovsthread_id_self
Unexecuted instantiation: dpif-netlink-rtnl.c:ovsthread_id_self
Unexecuted instantiation: dpif-offload-tc.c:ovsthread_id_self
Unexecuted instantiation: dpif-offload-tc-netdev.c:ovsthread_id_self
Unexecuted instantiation: netlink-conntrack.c:ovsthread_id_self
Unexecuted instantiation: netlink-notifier.c:ovsthread_id_self
Unexecuted instantiation: conntrack.c:ovsthread_id_self
Unexecuted instantiation: ct-dpif.c:ovsthread_id_self
Unexecuted instantiation: dpctl.c:ovsthread_id_self
Unexecuted instantiation: dpif-netdev.c:ovsthread_id_self
Unexecuted instantiation: fat-rwlock.c:ovsthread_id_self
Unexecuted instantiation: hindex.c:ovsthread_id_self
Unexecuted instantiation: ipf.c:ovsthread_id_self
Unexecuted instantiation: ovs-numa.c:ovsthread_id_self
Unexecuted instantiation: dpdk-stub.c:ovsthread_id_self
Unexecuted instantiation: vswitch-idl.c:ovsthread_id_self
Unexecuted instantiation: conntrack-icmp.c:ovsthread_id_self
Unexecuted instantiation: conntrack-tcp.c:ovsthread_id_self
Unexecuted instantiation: conntrack-tp.c:ovsthread_id_self
Unexecuted instantiation: conntrack-other.c:ovsthread_id_self
Unexecuted instantiation: dpif-netdev-dpcls.c:ovsthread_id_self
Unexecuted instantiation: dpif-netdev-perf.c:ovsthread_id_self
Unexecuted instantiation: ovsdb-data.c:ovsthread_id_self
Unexecuted instantiation: ovsdb-idl.c:ovsthread_id_self
Unexecuted instantiation: ovsdb-types.c:ovsthread_id_self
474

475
/* Simulated global counter.
476
 *
477
 * Incrementing such a counter is meant to be cheaper than incrementing a
478
 * global counter protected by a lock.  It is probably more expensive than
479
 * incrementing a truly thread-local variable, but such a variable has no
480
 * straightforward way to get the sum.
481
 *
482
 *
483
 * Thread-safety
484
 * =============
485
 *
486
 * Fully thread-safe. */
487
488
struct ovsthread_stats {
489
    struct ovs_mutex mutex;
490
    void *volatile buckets[16];
491
};
492
493
void ovsthread_stats_init(struct ovsthread_stats *);
494
void ovsthread_stats_destroy(struct ovsthread_stats *);
495
496
void *ovsthread_stats_bucket_get(struct ovsthread_stats *,
497
                                 void *(*new_bucket)(void));
498
499
#define OVSTHREAD_STATS_FOR_EACH_BUCKET(BUCKET, IDX, STATS)             \
500
    for ((IDX) = ovs_thread_stats_next_bucket(STATS, 0);                \
501
         ((IDX) < ARRAY_SIZE((STATS)->buckets)                          \
502
          ? ((BUCKET) = (STATS)->buckets[IDX], true)                    \
503
          : false);                                                     \
504
         (IDX) = ovs_thread_stats_next_bucket(STATS, (IDX) + 1))
505
size_t ovs_thread_stats_next_bucket(const struct ovsthread_stats *, size_t);
506

507
bool single_threaded(void);
508
509
void assert_single_threaded_at(const char *where);
510
0
#define assert_single_threaded() assert_single_threaded_at(OVS_SOURCE_LOCATOR)
511
512
pid_t xfork_at(const char *where);
513
0
#define xfork() xfork_at(OVS_SOURCE_LOCATOR)
514
515
void forbid_forking(const char *reason);
516
bool may_fork(void);
517

518
/* Useful functions related to threading. */
519
520
int count_cpu_cores(void);
521
int count_total_cores(void);
522
bool thread_is_pmd(void);
523
524
#endif /* ovs-thread.h */