DPDK 26.07.0-rc1
rte_ring_gcc_pvt.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright (c) 2010-2017 Intel Corporation
4 * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
5 * All rights reserved.
6 * Derived from FreeBSD's bufring.h
7 * Used as BSD-3 Licensed with permission from Kip Macy.
8 */
9
10#ifndef _RTE_RING_GCC_PVT_H_
11#define _RTE_RING_GCC_PVT_H_
12
48static __rte_always_inline unsigned int
49__rte_ring_headtail_move_head_st(struct rte_ring_headtail *d,
50 const struct rte_ring_headtail *s, uint32_t capacity,
51 unsigned int n,
52 enum rte_ring_queue_behavior behavior,
53 uint32_t *old_head, uint32_t *new_head, uint32_t *entries)
54{
55
56 *old_head = d->head;
57
58 /* add rmb barrier to avoid load/load reorder in weak
59 * memory model. It is noop on x86
60 */
62
63 /*
64 * The subtraction is done between two unsigned 32bits value
65 * (the result is always modulo 32 bits even if we have
66 * *old_head > s->tail). So 'entries' is always between 0
67 * and capacity (which is < size).
68 */
69 *entries = capacity + s->tail - *old_head;
70
71 /* check that we have enough room in ring */
72 if (unlikely(n > *entries))
73 n = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : *entries;
74
75 if (n == 0)
76 return 0;
77
78 *new_head = *old_head + n;
79 d->head = *new_head;
80 return n;
81}
82
109static __rte_always_inline unsigned int
110__rte_ring_headtail_move_head_mt(struct rte_ring_headtail *d,
111 const struct rte_ring_headtail *s, uint32_t capacity,
112 unsigned int n, enum rte_ring_queue_behavior behavior,
113 uint32_t *old_head, uint32_t *new_head, uint32_t *entries)
114{
115 unsigned int max = n;
116 bool success;
117
118 do {
119 /* Reset n to the initial burst count */
120 n = max;
121
122 *old_head = d->head;
123
124 /* add fence to avoid load/load reorder in weak
125 * memory model. It is noop on x86
126 */
127 __atomic_thread_fence(__ATOMIC_ACQUIRE);
128
129 /*
130 * The subtraction is done between two unsigned 32bits value
131 * (the result is always modulo 32 bits even if we have
132 * *old_head > s->tail). So 'entries' is always between 0
133 * and capacity (which is < size).
134 */
135 *entries = (capacity + s->tail - *old_head);
136
137 /* check that we have enough room in ring */
138 if (unlikely(n > *entries))
139 n = (behavior == RTE_RING_QUEUE_FIXED) ?
140 0 : *entries;
141
142 if (n == 0)
143 return 0;
144
145 *new_head = *old_head + n;
146
147 success = __sync_bool_compare_and_swap(
148 (uint32_t *)(uintptr_t)&d->head,
149 *old_head, *new_head);
150 } while (unlikely(!success));
151
152 return n;
153}
154
155#endif /* _RTE_RING_GCC_PVT_H_ */
static void rte_smp_rmb(void)
#define unlikely(x)
#define __rte_always_inline
Definition: rte_common.h:490
rte_ring_queue_behavior
Definition: rte_ring_core.h:40
@ RTE_RING_QUEUE_FIXED
Definition: rte_ring_core.h:42