Coverage Report

Created: 2025-07-01 06:51

/src/openvswitch/lib/ovs-thread.h
Line
Count
Source (jump to first uncovered line)
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(const struct ovs_rwlock *);
73
void ovs_rwlock_destroy(const 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
0
        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
#ifndef _WIN32
121
void xpthread_sigmask(int, const sigset_t *, sigset_t *);
122
#endif
123
124
pthread_t ovs_thread_create(const char *name, void *(*)(void *), void *);
125
void xpthread_join(pthread_t, void **);
126

127
/* Per-thread data.
128
 *
129
 *
130
 * Standard Forms
131
 * ==============
132
 *
133
 * Multiple forms of standard per-thread data exist, each with its own pluses
134
 * and minuses.  In general, if one of these forms is appropriate, then it's a
135
 * good idea to use it:
136
 *
137
 *     - POSIX per-thread data via pthread_key_t is portable to any pthreads
138
 *       implementation, and allows a destructor function to be defined.  It
139
 *       only (directly) supports per-thread pointers, which are always
140
 *       initialized to NULL.  It requires once-only allocation of a
141
 *       pthread_key_t value.  It is relatively slow.  Typically few
142
 *       "pthread_key_t"s are available (POSIX requires only at least 128,
143
 *       glibc supplies only 1024).
144
 *
145
 *     - The thread_local feature newly defined in C11 <threads.h> works with
146
 *       any data type and initializer, and it is fast.  thread_local does not
147
 *       require once-only initialization like pthread_key_t.  C11 does not
148
 *       define what happens if one attempts to access a thread_local object
149
 *       from a thread other than the one to which that object belongs.  There
150
 *       is no provision to call a user-specified destructor when a thread
151
 *       ends.  Typical implementations allow for an arbitrary amount of
152
 *       thread_local storage, but statically allocated only.
153
 *
154
 *     - The __thread keyword is a GCC extension similar to thread_local but
155
 *       with a longer history.  __thread is not portable to every GCC version
156
 *       or environment.  __thread does not restrict the use of a thread-local
157
 *       object outside its own thread.
158
 *
159
 * Here's a handy summary:
160
 *
161
 *                     pthread_key_t     thread_local       __thread
162
 *                     -------------     ------------     -------------
163
 * portability             high               low             medium
164
 * speed                    low              high               high
165
 * supports destructors?    yes                no                 no
166
 * needs key allocation?    yes                no                 no
167
 * arbitrary initializer?    no               yes                yes
168
 * cross-thread access?     yes                no                yes
169
 * amount available?        few            arbitrary         arbitrary
170
 * dynamically allocated?   yes                no                 no
171
 *
172
 *
173
 * Extensions
174
 * ==========
175
 *
176
 * OVS provides some extensions and wrappers:
177
 *
178
 *     - In a situation where the performance of thread_local or __thread is
179
 *       desirable, but portability is required, DEFINE_STATIC_PER_THREAD_DATA
180
 *       and DECLARE_EXTERN_PER_THREAD_DATA/DEFINE_EXTERN_PER_THREAD_DATA may
181
 *       be appropriate (see below).
182
 *
183
 *     - DEFINE_PER_THREAD_MALLOCED_DATA can be convenient for simple
184
 *       per-thread malloc()'d buffers.
185
 *
186
 *     - struct ovs_tsd provides an alternative to pthread_key_t that isn't
187
 *       limited to a small number of keys.
188
 */
189
190
/* For static data, use this macro in a source file:
191
 *
192
 *    DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, INITIALIZER).
193
 *
194
 * For global data, "declare" the data in the header and "define" it in
195
 * the source file, with:
196
 *
197
 *    DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME).
198
 *    DEFINE_EXTERN_PER_THREAD_DATA(NAME, INITIALIZER).
199
 *
200
 * One should prefer to use POSIX per-thread data, via pthread_key_t, when its
201
 * performance is acceptable, because of its portability (see the table above).
202
 * This macro is an alternatives that takes advantage of thread_local (and
203
 * __thread), for its performance, when it is available, and falls back to
204
 * POSIX per-thread data otherwise.
205
 *
206
 * Defines per-thread variable NAME with the given TYPE, initialized to
207
 * INITIALIZER (which must be valid as an initializer for a variable with
208
 * static lifetime).
209
 *
210
 * The public interface to the variable is:
211
 *
212
 *    TYPE *NAME_get(void)
213
 *    TYPE *NAME_get_unsafe(void)
214
 *
215
 *       Returns the address of this thread's instance of NAME.
216
 *
217
 *       Use NAME_get() in a context where this might be the first use of the
218
 *       per-thread variable in the program.  Use NAME_get_unsafe(), which
219
 *       avoids a conditional test and is thus slightly faster, in a context
220
 *       where one knows that NAME_get() has already been called previously.
221
 *
222
 * There is no "NAME_set()" (or "NAME_set_unsafe()") function.  To set the
223
 * value of the per-thread variable, dereference the pointer returned by
224
 * TYPE_get() or TYPE_get_unsafe(), e.g. *TYPE_get() = 0.
225
 */
226
#if HAVE_THREAD_LOCAL || HAVE___THREAD
227
228
#if HAVE_THREAD_LOCAL
229
#include <threads.h>
230
#elif HAVE___THREAD
231
#define thread_local __thread
232
#else
233
#error
234
#endif
235
236
#define DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, ...)                  \
237
    typedef TYPE NAME##_type;                                           \
238
                                                                        \
239
    static NAME##_type *                                                \
240
    NAME##_get_unsafe(void)                                             \
241
11.8M
    {                                                                   \
242
11.8M
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
11.8M
        return &var;                                                    \
244
11.8M
    }                                                                   \
util.c:counter_util_xalloc_get_unsafe
Line
Count
Source
241
11.7M
    {                                                                   \
242
11.7M
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
11.7M
        return &var;                                                    \
244
11.7M
    }                                                                   \
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
flow.c:counter_flow_extract_get_unsafe
Line
Count
Source
241
66.1k
    {                                                                   \
242
66.1k
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
66.1k
        return &var;                                                    \
244
66.1k
    }                                                                   \
flow.c:counter_miniflow_extract_ipv4_pkt_len_error_get_unsafe
Line
Count
Source
241
256
    {                                                                   \
242
256
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
256
        return &var;                                                    \
244
256
    }                                                                   \
flow.c:counter_miniflow_extract_ipv4_pkt_too_short_get_unsafe
Line
Count
Source
241
73
    {                                                                   \
242
73
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
73
        return &var;                                                    \
244
73
    }                                                                   \
flow.c:counter_miniflow_extract_ipv6_pkt_len_error_get_unsafe
Line
Count
Source
241
352
    {                                                                   \
242
352
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
352
        return &var;                                                    \
244
352
    }                                                                   \
flow.c:counter_miniflow_extract_ipv6_pkt_too_short_get_unsafe
Line
Count
Source
241
381
    {                                                                   \
242
381
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
381
        return &var;                                                    \
244
381
    }                                                                   \
flow.c:counter_miniflow_malloc_get_unsafe
Line
Count
Source
241
46.4k
    {                                                                   \
242
46.4k
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
46.4k
        return &var;                                                    \
244
46.4k
    }                                                                   \
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: netdev.c:counter_netdev_soft_seg_good_get_unsafe
Unexecuted instantiation: netdev.c:counter_netdev_soft_seg_drops_get_unsafe
Unexecuted instantiation: poll-loop.c:counter_poll_create_node_get_unsafe
Unexecuted instantiation: poll-loop.c:counter_poll_zero_timeout_get_unsafe
Unexecuted instantiation: random.c:seed_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
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
hmap.c:counter_hmap_pathological_get_unsafe
Line
Count
Source
241
6
    {                                                                   \
242
6
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
6
        return &var;                                                    \
244
6
    }                                                                   \
hmap.c:counter_hmap_expand_get_unsafe
Line
Count
Source
241
28
    {                                                                   \
242
28
        static thread_local NAME##_type var = __VA_ARGS__;              \
243
28
        return &var;                                                    \
244
28
    }                                                                   \
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: 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: stream.c:counter_pstream_open_get_unsafe
Unexecuted instantiation: stream.c:counter_stream_open_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: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: 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: process.c:counter_process_start_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
245
                                                                        \
246
    static NAME##_type *                                                \
247
    NAME##_get(void)                                                    \
248
11.8M
    {                                                                   \
249
11.8M
        return NAME##_get_unsafe();                                     \
250
11.8M
    }
util.c:counter_util_xalloc_get
Line
Count
Source
248
11.7M
    {                                                                   \
249
11.7M
        return NAME##_get_unsafe();                                     \
250
11.7M
    }
Unexecuted instantiation: util.c:strerror_buffer_get
Unexecuted instantiation: vlog.c:msg_num_get
Unexecuted instantiation: coverage.c:coverage_clear_time_get
flow.c:counter_flow_extract_get
Line
Count
Source
248
66.1k
    {                                                                   \
249
66.1k
        return NAME##_get_unsafe();                                     \
250
66.1k
    }
flow.c:counter_miniflow_extract_ipv4_pkt_len_error_get
Line
Count
Source
248
256
    {                                                                   \
249
256
        return NAME##_get_unsafe();                                     \
250
256
    }
flow.c:counter_miniflow_extract_ipv4_pkt_too_short_get
Line
Count
Source
248
73
    {                                                                   \
249
73
        return NAME##_get_unsafe();                                     \
250
73
    }
flow.c:counter_miniflow_extract_ipv6_pkt_len_error_get
Line
Count
Source
248
352
    {                                                                   \
249
352
        return NAME##_get_unsafe();                                     \
250
352
    }
flow.c:counter_miniflow_extract_ipv6_pkt_too_short_get
Line
Count
Source
248
381
    {                                                                   \
249
381
        return NAME##_get_unsafe();                                     \
250
381
    }
flow.c:counter_miniflow_malloc_get
Line
Count
Source
248
46.4k
    {                                                                   \
249
46.4k
        return NAME##_get_unsafe();                                     \
250
46.4k
    }
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: netdev.c:counter_netdev_soft_seg_good_get
Unexecuted instantiation: netdev.c:counter_netdev_soft_seg_drops_get
Unexecuted instantiation: poll-loop.c:counter_poll_create_node_get
Unexecuted instantiation: poll-loop.c:counter_poll_zero_timeout_get
Unexecuted instantiation: random.c:seed_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
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
hmap.c:counter_hmap_pathological_get
Line
Count
Source
248
6
    {                                                                   \
249
6
        return NAME##_get_unsafe();                                     \
250
6
    }
hmap.c:counter_hmap_expand_get
Line
Count
Source
248
28
    {                                                                   \
249
28
        return NAME##_get_unsafe();                                     \
250
28
    }
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: 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: stream.c:counter_pstream_open_get
Unexecuted instantiation: stream.c:counter_stream_open_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: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: lockfile.c:counter_lockfile_lock_get
Unexecuted instantiation: lockfile.c:counter_lockfile_error_get
Unexecuted instantiation: lockfile.c:counter_lockfile_unlock_get
Unexecuted instantiation: process.c:counter_process_start_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
251
#define DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME)                      \
252
    typedef TYPE NAME##_type;                                           \
253
    extern thread_local NAME##_type NAME##_var;                         \
254
                                                                        \
255
    static inline NAME##_type *                                         \
256
    NAME##_get_unsafe(void)                                             \
257
0
    {                                                                   \
258
0
        return (NAME##_type *)&NAME##_var;                              \
259
0
    }                                                                   \
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: coverage.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dp-packet.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dp-packet.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: flow.c:ovsthread_id_get_unsafe
Unexecuted instantiation: flow.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: meta-flow.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: ofp-msgs.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: 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: random.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: tnl-ports.c:ovsthread_id_get_unsafe
Unexecuted instantiation: unixctl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: userspace-tso.c:ovsthread_id_get_unsafe
Unexecuted instantiation: uuid.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-linux.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-linux.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: netdev-offload-tc.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-offload-tc.c:netdev_offload_thread_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: ccmap.c:ovsthread_id_get_unsafe
Unexecuted instantiation: cmap.c:ovsthread_id_get_unsafe
Unexecuted instantiation: command-line.c:ovsthread_id_get_unsafe
Unexecuted instantiation: connectivity.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dp-packet-gso.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dp-packet-gso.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: dpif.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: fatal-signal.c:ovsthread_id_get_unsafe
Unexecuted instantiation: guarded-list.c:ovsthread_id_get_unsafe
Unexecuted instantiation: hmap.c:ovsthread_id_get_unsafe
Unexecuted instantiation: jsonrpc.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-offload.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: netdev-offload.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-vport.c:ovsthread_id_get_unsafe
Unexecuted instantiation: netdev-vport.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: netlink.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: stream.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: netdev-native-tnl.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: daemon-unix.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netlink.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netlink.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: dpif-netlink-rtnl.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: stream-ssl.c:ovsthread_id_get_unsafe
Unexecuted instantiation: conntrack.c:ovsthread_id_get_unsafe
Unexecuted instantiation: daemon.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netdev.c:netdev_offload_thread_id_get_unsafe
Unexecuted instantiation: dpif-netdev.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netdev-private-extract.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netdev-perf.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: lockfile.c:ovsthread_id_get_unsafe
Unexecuted instantiation: ovs-numa.c:ovsthread_id_get_unsafe
Unexecuted instantiation: process.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-extract-study.c:ovsthread_id_get_unsafe
Unexecuted instantiation: dpif-netdev-lookup-generic.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
260
                                                                        \
261
    static inline NAME##_type *                                         \
262
    NAME##_get(void)                                                    \
263
0
    {                                                                   \
264
0
        return NAME##_get_unsafe();                                     \
265
0
    }
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: coverage.c:ovsthread_id_get
Unexecuted instantiation: dp-packet.c:ovsthread_id_get
Unexecuted instantiation: dp-packet.c:netdev_offload_thread_id_get
Unexecuted instantiation: flow.c:ovsthread_id_get
Unexecuted instantiation: flow.c:netdev_offload_thread_id_get
Unexecuted instantiation: meta-flow.c:ovsthread_id_get
Unexecuted instantiation: netdev.c:ovsthread_id_get
Unexecuted instantiation: netdev.c:netdev_offload_thread_id_get
Unexecuted instantiation: ofp-msgs.c:ovsthread_id_get
Unexecuted instantiation: ovs-rcu.c:ovsthread_id_get
Unexecuted instantiation: ovs-router.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: random.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: tnl-ports.c:ovsthread_id_get
Unexecuted instantiation: unixctl.c:ovsthread_id_get
Unexecuted instantiation: userspace-tso.c:ovsthread_id_get
Unexecuted instantiation: uuid.c:ovsthread_id_get
Unexecuted instantiation: netdev-linux.c:ovsthread_id_get
Unexecuted instantiation: netdev-linux.c:netdev_offload_thread_id_get
Unexecuted instantiation: netdev-offload-tc.c:ovsthread_id_get
Unexecuted instantiation: netdev-offload-tc.c:netdev_offload_thread_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: ccmap.c:ovsthread_id_get
Unexecuted instantiation: cmap.c:ovsthread_id_get
Unexecuted instantiation: command-line.c:ovsthread_id_get
Unexecuted instantiation: connectivity.c:ovsthread_id_get
Unexecuted instantiation: dp-packet-gso.c:ovsthread_id_get
Unexecuted instantiation: dp-packet-gso.c:netdev_offload_thread_id_get
Unexecuted instantiation: dpif.c:ovsthread_id_get
Unexecuted instantiation: dpif.c:netdev_offload_thread_id_get
Unexecuted instantiation: fatal-signal.c:ovsthread_id_get
Unexecuted instantiation: guarded-list.c:ovsthread_id_get
Unexecuted instantiation: hmap.c:ovsthread_id_get
Unexecuted instantiation: jsonrpc.c:ovsthread_id_get
Unexecuted instantiation: netdev-offload.c:netdev_offload_thread_id_get
Unexecuted instantiation: netdev-offload.c:ovsthread_id_get
Unexecuted instantiation: netdev-vport.c:ovsthread_id_get
Unexecuted instantiation: netdev-vport.c:netdev_offload_thread_id_get
Unexecuted instantiation: netlink.c:ovsthread_id_get
Unexecuted instantiation: odp-execute.c:ovsthread_id_get
Unexecuted instantiation: odp-util.c:ovsthread_id_get
Unexecuted instantiation: stream.c:ovsthread_id_get
Unexecuted instantiation: tnl-neigh-cache.c:ovsthread_id_get
Unexecuted instantiation: netdev-native-tnl.c:ovsthread_id_get
Unexecuted instantiation: netdev-native-tnl.c:netdev_offload_thread_id_get
Unexecuted instantiation: daemon-unix.c:ovsthread_id_get
Unexecuted instantiation: dpif-netlink.c:ovsthread_id_get
Unexecuted instantiation: dpif-netlink.c:netdev_offload_thread_id_get
Unexecuted instantiation: dpif-netlink-rtnl.c:ovsthread_id_get
Unexecuted instantiation: netlink-conntrack.c:ovsthread_id_get
Unexecuted instantiation: netlink-notifier.c:ovsthread_id_get
Unexecuted instantiation: stream-ssl.c:ovsthread_id_get
Unexecuted instantiation: conntrack.c:ovsthread_id_get
Unexecuted instantiation: daemon.c:ovsthread_id_get
Unexecuted instantiation: dpif-netdev.c:netdev_offload_thread_id_get
Unexecuted instantiation: dpif-netdev.c:ovsthread_id_get
Unexecuted instantiation: dpif-netdev-private-extract.c:ovsthread_id_get
Unexecuted instantiation: dpif-netdev-perf.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: lockfile.c:ovsthread_id_get
Unexecuted instantiation: ovs-numa.c:ovsthread_id_get
Unexecuted instantiation: process.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-extract-study.c:ovsthread_id_get
Unexecuted instantiation: dpif-netdev-lookup-generic.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
266
#define DEFINE_EXTERN_PER_THREAD_DATA(NAME, ...)         \
267
    thread_local NAME##_type NAME##_var = __VA_ARGS__;
268
#else  /* no C implementation support for thread-local storage  */
269
#define DEFINE_STATIC_PER_THREAD_DATA(TYPE, NAME, ...)                  \
270
    typedef TYPE NAME##_type;                                           \
271
    static pthread_key_t NAME##_key;                                    \
272
                                                                        \
273
    static NAME##_type *                                                \
274
    NAME##_get_unsafe(void)                                             \
275
    {                                                                   \
276
        return pthread_getspecific(NAME##_key);                         \
277
    }                                                                   \
278
                                                                        \
279
    static void                                                         \
280
    NAME##_once_init(void)                                              \
281
    {                                                                   \
282
        if (pthread_key_create(&NAME##_key, free)) {                    \
283
            abort();                                                    \
284
        }                                                               \
285
    }                                                                   \
286
                                                                        \
287
    static NAME##_type *                                                \
288
    NAME##_get(void)                                                    \
289
    {                                                                   \
290
        static pthread_once_t once = PTHREAD_ONCE_INIT;                 \
291
        NAME##_type *value;                                             \
292
                                                                        \
293
        pthread_once(&once, NAME##_once_init);                          \
294
        value = NAME##_get_unsafe();                                    \
295
        if (!value) {                                                   \
296
            static const NAME##_type initial_value = __VA_ARGS__;       \
297
                                                                        \
298
            value = xmalloc__(sizeof *value);                           \
299
            *value = initial_value;                                     \
300
            xpthread_setspecific(NAME##_key, value);                    \
301
        }                                                               \
302
        return value;                                                   \
303
    }
304
#define DECLARE_EXTERN_PER_THREAD_DATA(TYPE, NAME)                      \
305
    typedef TYPE NAME##_type;                                           \
306
    static pthread_key_t NAME##_key;                                    \
307
                                                                        \
308
    static inline NAME##_type *                                         \
309
    NAME##_get_unsafe(void)                                             \
310
    {                                                                   \
311
        return (NAME##_type *)pthread_getspecific(NAME##_key);          \
312
    }                                                                   \
313
                                                                        \
314
    NAME##_type *NAME##_get(void);
315
#define DEFINE_EXTERN_PER_THREAD_DATA(NAME, ...)                        \
316
    static void                                                         \
317
    NAME##_once_init(void)                                              \
318
    {                                                                   \
319
        if (pthread_key_create(&NAME##_key, free)) {                    \
320
            abort();                                                    \
321
        }                                                               \
322
    }                                                                   \
323
                                                                        \
324
    NAME##_type *                                                       \
325
    NAME##_get(void)                                                    \
326
    {                                                                   \
327
        static pthread_once_t once = PTHREAD_ONCE_INIT;                 \
328
        NAME##_type *value;                                             \
329
                                                                        \
330
        pthread_once(&once, NAME##_once_init);                          \
331
        value = NAME##_get_unsafe();                                    \
332
        if (!value) {                                                   \
333
            static const NAME##_type initial_value = __VA_ARGS__;       \
334
                                                                        \
335
            value = xmalloc__(sizeof *value);                           \
336
            *value = initial_value;                                     \
337
            xpthread_setspecific(NAME##_key, value);                    \
338
        }                                                               \
339
        return value;                                                   \
340
    }
341
#endif
342
343
/* DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME).
344
 *
345
 * This is a simple wrapper around POSIX per-thread data primitives.  It
346
 * defines per-thread variable NAME with the given TYPE, which must be a
347
 * pointer type.  In each thread, the per-thread variable is initialized to
348
 * NULL.  When a thread terminates, the variable is freed with free().
349
 *
350
 * The public interface to the variable is:
351
 *
352
 *    TYPE NAME_get(void)
353
 *    TYPE NAME_get_unsafe(void)
354
 *
355
 *       Returns the value of per-thread variable NAME in this thread.
356
 *
357
 *       Use NAME_get() in a context where this might be the first use of the
358
 *       per-thread variable in the program.  Use NAME_get_unsafe(), which
359
 *       avoids a conditional test and is thus slightly faster, in a context
360
 *       where one knows that NAME_get() has already been called previously.
361
 *
362
 *    TYPE NAME_set(TYPE new_value)
363
 *    TYPE NAME_set_unsafe(TYPE new_value)
364
 *
365
 *       Sets the value of per-thread variable NAME to 'new_value' in this
366
 *       thread, and returns its previous value.
367
 *
368
 *       Use NAME_set() in a context where this might be the first use of the
369
 *       per-thread variable in the program.  Use NAME_set_unsafe(), which
370
 *       avoids a conditional test and is thus slightly faster, in a context
371
 *       where one knows that NAME_set() has already been called previously.
372
 */
373
#define DEFINE_PER_THREAD_MALLOCED_DATA(TYPE, NAME)     \
374
    static pthread_key_t NAME##_key;                    \
375
                                                        \
376
    static void                                         \
377
    NAME##_once_init(void)                              \
378
0
    {                                                   \
379
0
        if (pthread_key_create(&NAME##_key, free)) {    \
380
0
            abort();                                    \
381
0
        }                                               \
382
0
    }                                                   \
Unexecuted instantiation: util.c:subprogram_name_once_init
Unexecuted instantiation: timeval.c:cpu_tracker_var_once_init
Unexecuted instantiation: dpif-netdev-extract-study.c:study_stats_once_init
Unexecuted instantiation: dpif-netdev-lookup-generic.c:block_array_once_init
383
                                                        \
384
    static void                                         \
385
    NAME##_init(void)                                   \
386
0
    {                                                   \
387
0
        static pthread_once_t once = PTHREAD_ONCE_INIT; \
388
0
        pthread_once(&once, NAME##_once_init);          \
389
0
    }                                                   \
Unexecuted instantiation: util.c:subprogram_name_init
Unexecuted instantiation: timeval.c:cpu_tracker_var_init
Unexecuted instantiation: dpif-netdev-extract-study.c:study_stats_init
Unexecuted instantiation: dpif-netdev-lookup-generic.c:block_array_init
390
                                                        \
391
    static TYPE                                         \
392
    NAME##_get_unsafe(void)                             \
393
0
    {                                                   \
394
0
        return pthread_getspecific(NAME##_key);         \
395
0
    }                                                   \
Unexecuted instantiation: util.c:subprogram_name_get_unsafe
Unexecuted instantiation: timeval.c:cpu_tracker_var_get_unsafe
Unexecuted instantiation: dpif-netdev-extract-study.c:study_stats_get_unsafe
Unexecuted instantiation: dpif-netdev-lookup-generic.c:block_array_get_unsafe
396
                                                        \
397
    static OVS_UNUSED TYPE                              \
398
    NAME##_get(void)                                    \
399
0
    {                                                   \
400
0
        NAME##_init();                                  \
401
0
        return NAME##_get_unsafe();                     \
402
0
    }                                                   \
Unexecuted instantiation: util.c:subprogram_name_get
Unexecuted instantiation: timeval.c:cpu_tracker_var_get
Unexecuted instantiation: dpif-netdev-extract-study.c:study_stats_get
Unexecuted instantiation: dpif-netdev-lookup-generic.c:block_array_get
403
                                                        \
404
    static TYPE                                         \
405
    NAME##_set_unsafe(TYPE value)                       \
406
0
    {                                                   \
407
0
        TYPE old_value = NAME##_get_unsafe();           \
408
0
        xpthread_setspecific(NAME##_key, value);        \
409
0
        return old_value;                               \
410
0
    }                                                   \
Unexecuted instantiation: util.c:subprogram_name_set_unsafe
Unexecuted instantiation: timeval.c:cpu_tracker_var_set_unsafe
Unexecuted instantiation: dpif-netdev-extract-study.c:study_stats_set_unsafe
Unexecuted instantiation: dpif-netdev-lookup-generic.c:block_array_set_unsafe
411
                                                        \
412
    static OVS_UNUSED TYPE                              \
413
    NAME##_set(TYPE value)                              \
414
0
    {                                                   \
415
0
        NAME##_init();                                  \
416
0
        return NAME##_set_unsafe(value);                \
417
0
    }
Unexecuted instantiation: util.c:subprogram_name_set
Unexecuted instantiation: timeval.c:cpu_tracker_var_set
Unexecuted instantiation: dpif-netdev-extract-study.c:study_stats_set
Unexecuted instantiation: dpif-netdev-lookup-generic.c:block_array_set
418
419
/* Dynamically allocated thread-specific data with lots of slots.
420
 *
421
 * pthread_key_t can provide as few as 128 pieces of thread-specific data (even
422
 * glibc is limited to 1,024).  Thus, one must be careful to allocate only a
423
 * few keys globally.  One cannot, for example, allocate a key for every
424
 * instance of a data structure if there might be an arbitrary number of those
425
 * data structures.
426
 *
427
 * This API is similar to the pthread one (simply search and replace pthread_
428
 * by ovsthread_) but it a much larger limit that can be raised if necessary
429
 * (by recompiling).  Thus, one may more freely use this form of
430
 * thread-specific data.
431
 *
432
 * ovsthread_key_t also differs from pthread_key_t in the following ways:
433
 *
434
 *    - Destructors must not access thread-specific data (via ovsthread_key).
435
 *
436
 *    - The pthread_key_t API allows concurrently exiting threads to start
437
 *      executing the destructor after pthread_key_delete() returns.  The
438
 *      ovsthread_key_t API guarantees that, when ovsthread_key_delete()
439
 *      returns, all destructors have returned and no new ones will start
440
 *      execution.
441
 */
442
typedef struct ovsthread_key *ovsthread_key_t;
443
444
void ovsthread_key_create(ovsthread_key_t *, void (*destructor)(void *));
445
void ovsthread_key_delete(ovsthread_key_t);
446
447
void ovsthread_setspecific(ovsthread_key_t, const void *);
448
void *ovsthread_getspecific(ovsthread_key_t);
449

450
/* Thread ID.
451
 *
452
 * pthread_t isn't so nice for some purposes.  Its size and representation are
453
 * implementation dependent, which means that there is no way to hash it.
454
 * This thread ID avoids the problem.
455
 */
456
457
0
#define OVSTHREAD_ID_UNSET UINT_MAX
458
DECLARE_EXTERN_PER_THREAD_DATA(unsigned int, ovsthread_id);
459
460
/* Initializes the unique per thread identifier */
461
unsigned int ovsthread_id_init(void);
462
463
/* Returns a per-thread identifier unique within the lifetime of the
464
 * process. */
465
static inline unsigned int
466
ovsthread_id_self(void)
467
0
{
468
0
    unsigned int id = *ovsthread_id_get();
469
470
0
    if (OVS_UNLIKELY(id == OVSTHREAD_ID_UNSET)) {
471
0
        id = ovsthread_id_init();
472
0
    }
473
474
0
    return id;
475
0
}
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: coverage.c:ovsthread_id_self
Unexecuted instantiation: dp-packet.c:ovsthread_id_self
Unexecuted instantiation: flow.c:ovsthread_id_self
Unexecuted instantiation: meta-flow.c:ovsthread_id_self
Unexecuted instantiation: netdev.c:ovsthread_id_self
Unexecuted instantiation: ofp-msgs.c:ovsthread_id_self
Unexecuted instantiation: ovs-rcu.c:ovsthread_id_self
Unexecuted instantiation: ovs-router.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: random.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: tnl-ports.c:ovsthread_id_self
Unexecuted instantiation: unixctl.c:ovsthread_id_self
Unexecuted instantiation: userspace-tso.c:ovsthread_id_self
Unexecuted instantiation: uuid.c:ovsthread_id_self
Unexecuted instantiation: netdev-linux.c:ovsthread_id_self
Unexecuted instantiation: netdev-offload-tc.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: ccmap.c:ovsthread_id_self
Unexecuted instantiation: cmap.c:ovsthread_id_self
Unexecuted instantiation: command-line.c:ovsthread_id_self
Unexecuted instantiation: connectivity.c:ovsthread_id_self
Unexecuted instantiation: dp-packet-gso.c:ovsthread_id_self
Unexecuted instantiation: dpif.c:ovsthread_id_self
Unexecuted instantiation: fatal-signal.c:ovsthread_id_self
Unexecuted instantiation: guarded-list.c:ovsthread_id_self
Unexecuted instantiation: hmap.c:ovsthread_id_self
Unexecuted instantiation: jsonrpc.c:ovsthread_id_self
Unexecuted instantiation: netdev-offload.c:ovsthread_id_self
Unexecuted instantiation: netdev-vport.c:ovsthread_id_self
Unexecuted instantiation: netlink.c:ovsthread_id_self
Unexecuted instantiation: odp-execute.c:ovsthread_id_self
Unexecuted instantiation: odp-util.c:ovsthread_id_self
Unexecuted instantiation: stream.c:ovsthread_id_self
Unexecuted instantiation: tnl-neigh-cache.c:ovsthread_id_self
Unexecuted instantiation: netdev-native-tnl.c:ovsthread_id_self
Unexecuted instantiation: daemon-unix.c:ovsthread_id_self
Unexecuted instantiation: dpif-netlink.c:ovsthread_id_self
Unexecuted instantiation: dpif-netlink-rtnl.c:ovsthread_id_self
Unexecuted instantiation: netlink-conntrack.c:ovsthread_id_self
Unexecuted instantiation: netlink-notifier.c:ovsthread_id_self
Unexecuted instantiation: stream-ssl.c:ovsthread_id_self
Unexecuted instantiation: conntrack.c:ovsthread_id_self
Unexecuted instantiation: daemon.c:ovsthread_id_self
Unexecuted instantiation: dpif-netdev.c:ovsthread_id_self
Unexecuted instantiation: dpif-netdev-private-extract.c:ovsthread_id_self
Unexecuted instantiation: dpif-netdev-perf.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: lockfile.c:ovsthread_id_self
Unexecuted instantiation: ovs-numa.c:ovsthread_id_self
Unexecuted instantiation: process.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-extract-study.c:ovsthread_id_self
Unexecuted instantiation: dpif-netdev-lookup-generic.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
476

477
/* Simulated global counter.
478
 *
479
 * Incrementing such a counter is meant to be cheaper than incrementing a
480
 * global counter protected by a lock.  It is probably more expensive than
481
 * incrementing a truly thread-local variable, but such a variable has no
482
 * straightforward way to get the sum.
483
 *
484
 *
485
 * Thread-safety
486
 * =============
487
 *
488
 * Fully thread-safe. */
489
490
struct ovsthread_stats {
491
    struct ovs_mutex mutex;
492
    void *volatile buckets[16];
493
};
494
495
void ovsthread_stats_init(struct ovsthread_stats *);
496
void ovsthread_stats_destroy(struct ovsthread_stats *);
497
498
void *ovsthread_stats_bucket_get(struct ovsthread_stats *,
499
                                 void *(*new_bucket)(void));
500
501
#define OVSTHREAD_STATS_FOR_EACH_BUCKET(BUCKET, IDX, STATS)             \
502
    for ((IDX) = ovs_thread_stats_next_bucket(STATS, 0);                \
503
         ((IDX) < ARRAY_SIZE((STATS)->buckets)                          \
504
          ? ((BUCKET) = (STATS)->buckets[IDX], true)                    \
505
          : false);                                                     \
506
         (IDX) = ovs_thread_stats_next_bucket(STATS, (IDX) + 1))
507
size_t ovs_thread_stats_next_bucket(const struct ovsthread_stats *, size_t);
508

509
bool single_threaded(void);
510
511
void assert_single_threaded_at(const char *where);
512
0
#define assert_single_threaded() assert_single_threaded_at(OVS_SOURCE_LOCATOR)
513
514
#ifndef _WIN32
515
pid_t xfork_at(const char *where);
516
0
#define xfork() xfork_at(OVS_SOURCE_LOCATOR)
517
#endif
518
519
void forbid_forking(const char *reason);
520
bool may_fork(void);
521

522
/* Useful functions related to threading. */
523
524
int count_cpu_cores(void);
525
int count_total_cores(void);
526
bool thread_is_pmd(void);
527
528
#endif /* ovs-thread.h */