DPDK
22.11.5
Loading...
Searching...
No Matches
lib
eal
include
rte_pflock.h
Go to the documentation of this file.
1
/* SPDX-License-Identifier: BSD-3-Clause
2
* Copyright(c) 2021 Microsoft Corp.
3
* All rights reserved.
4
*
5
* Derived from Concurrency Kit
6
* Copyright 2011-2015 Samy Al Bahra.
7
*/
8
9
#ifndef _RTE_PFLOCK_H_
10
#define _RTE_PFLOCK_H_
11
30
#ifdef __cplusplus
31
extern
"C"
{
32
#endif
33
34
#include <rte_compat.h>
35
#include <
rte_common.h
>
36
#include <
rte_pause.h
>
37
41
struct
rte_pflock
{
42
struct
{
43
uint16_t in;
44
uint16_t out;
45
} rd, wr;
46
};
47
typedef
struct
rte_pflock
rte_pflock_t
;
48
49
/*
50
* Allocation of bits to reader
51
*
52
* 15 4 3 2 1 0
53
* +-------------------+---+-+-+
54
* | rin: reads issued |x|x| | |
55
* +-------------------+---+-+-+
56
* ^ ^
57
* | |
58
* PRES: writer present ----/ |
59
* PHID: writer phase id -----/
60
*
61
* 15 4 3 2 1 0
62
* +------------------+------+
63
* |rout:read complete|unused|
64
* +------------------+------+
65
*
66
* The maximum number of readers is 4095
67
*/
68
69
/* Constants used to map the bits in reader counter */
70
#define RTE_PFLOCK_WBITS 0x3
/* Writer bits in reader. */
71
#define RTE_PFLOCK_PRES 0x2
/* Writer present bit. */
72
#define RTE_PFLOCK_PHID 0x1
/* Phase ID bit. */
73
#define RTE_PFLOCK_LSB 0xFFF0
/* reader bits. */
74
#define RTE_PFLOCK_RINC 0x10
/* Reader increment. */
75
79
#define RTE_PFLOCK_INITIALIZER { }
80
90
__rte_experimental
91
static
inline
void
92
rte_pflock_init
(
struct
rte_pflock
*pf)
93
{
94
pf->rd.in = 0;
95
pf->rd.out = 0;
96
pf->wr.in = 0;
97
pf->wr.out = 0;
98
}
99
109
__rte_experimental
110
static
inline
void
111
rte_pflock_read_lock
(
rte_pflock_t
*pf)
112
{
113
uint16_t w;
114
115
/*
116
* If no writer is present, then the operation has completed
117
* successfully.
118
*/
119
w = __atomic_fetch_add(&pf->rd.in, RTE_PFLOCK_RINC, __ATOMIC_ACQUIRE)
120
& RTE_PFLOCK_WBITS;
121
if
(w == 0)
122
return
;
123
124
/* Wait for current write phase to complete. */
125
RTE_WAIT_UNTIL_MASKED(&pf->rd.in, RTE_PFLOCK_WBITS, !=, w,
126
__ATOMIC_ACQUIRE);
127
}
128
138
__rte_experimental
139
static
inline
void
140
rte_pflock_read_unlock
(
rte_pflock_t
*pf)
141
{
142
__atomic_fetch_add(&pf->rd.out, RTE_PFLOCK_RINC, __ATOMIC_RELEASE);
143
}
144
154
__rte_experimental
155
static
inline
void
156
rte_pflock_write_lock
(
rte_pflock_t
*pf)
157
{
158
uint16_t ticket, w;
159
160
/* Acquire ownership of write-phase.
161
* This is same as rte_ticketlock_lock().
162
*/
163
ticket = __atomic_fetch_add(&pf->wr.in, 1, __ATOMIC_RELAXED);
164
rte_wait_until_equal_16
(&pf->wr.out, ticket, __ATOMIC_ACQUIRE);
165
166
/*
167
* Acquire ticket on read-side in order to allow them
168
* to flush. Indicates to any incoming reader that a
169
* write-phase is pending.
170
*
171
* The load of rd.out in wait loop could be executed
172
* speculatively.
173
*/
174
w = RTE_PFLOCK_PRES | (ticket & RTE_PFLOCK_PHID);
175
ticket = __atomic_fetch_add(&pf->rd.in, w, __ATOMIC_RELAXED);
176
177
/* Wait for any pending readers to flush. */
178
rte_wait_until_equal_16
(&pf->rd.out, ticket, __ATOMIC_ACQUIRE);
179
}
180
190
__rte_experimental
191
static
inline
void
192
rte_pflock_write_unlock
(
rte_pflock_t
*pf)
193
{
194
/* Migrate from write phase to read phase. */
195
__atomic_fetch_and(&pf->rd.in, RTE_PFLOCK_LSB, __ATOMIC_RELEASE);
196
197
/* Allow other writers to continue. */
198
__atomic_fetch_add(&pf->wr.out, 1, __ATOMIC_RELEASE);
199
}
200
201
#ifdef __cplusplus
202
}
203
#endif
204
205
#endif
/* RTE_PFLOCK_H */
rte_common.h
rte_pause.h
rte_wait_until_equal_16
static __rte_always_inline void rte_wait_until_equal_16(volatile uint16_t *addr, uint16_t expected, int memorder)
Definition
rte_pause.h:85
rte_pflock_read_lock
static __rte_experimental void rte_pflock_read_lock(rte_pflock_t *pf)
Definition
rte_pflock.h:111
rte_pflock_write_unlock
static __rte_experimental void rte_pflock_write_unlock(rte_pflock_t *pf)
Definition
rte_pflock.h:192
rte_pflock_write_lock
static __rte_experimental void rte_pflock_write_lock(rte_pflock_t *pf)
Definition
rte_pflock.h:156
rte_pflock_init
static __rte_experimental void rte_pflock_init(struct rte_pflock *pf)
Definition
rte_pflock.h:92
rte_pflock_read_unlock
static __rte_experimental void rte_pflock_read_unlock(rte_pflock_t *pf)
Definition
rte_pflock.h:140
rte_pflock
Definition
rte_pflock.h:41
Generated by
1.12.0