Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright (c) 2010-2020 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_PEEK_ELEM_PVT_H_
11 : : #define _RTE_RING_PEEK_ELEM_PVT_H_
12 : :
13 : : /**
14 : : * @file rte_ring_peek_elem_pvt.h
15 : : * It is not recommended to include this file directly,
16 : : * include <rte_ring.h> instead.
17 : : * Contains internal helper functions for rte_ring peek API.
18 : : * For more information please refer to <rte_ring_peek.h>.
19 : : */
20 : :
21 : : /**
22 : : * @internal get current tail value.
23 : : * This function should be used only for single thread producer/consumer.
24 : : * Check that user didn't request to move tail above the head.
25 : : * In that situation:
26 : : * - return zero, that will cause abort any pending changes and
27 : : * return head to its previous position.
28 : : * - throw an assert in debug mode.
29 : : */
30 : : static __rte_always_inline uint32_t
31 : : __rte_ring_st_get_tail(struct rte_ring_headtail *ht, uint32_t *tail,
32 : : uint32_t num)
33 : : {
34 : : uint32_t h, n, t;
35 : :
36 : 5520 : h = ht->head;
37 : 5520 : t = ht->tail;
38 : 5520 : n = h - t;
39 : :
40 : : RTE_ASSERT(n >= num);
41 [ - + - + : 5520 : num = (n >= num) ? num : 0;
- + - + -
+ - + - +
- + # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
42 : :
43 : : *tail = t;
44 : : return num;
45 : : }
46 : :
47 : : /**
48 : : * @internal set new values for head and tail.
49 : : * This function should be used only for single thread producer/consumer.
50 : : * Should be used only in conjunction with __rte_ring_st_get_tail.
51 : : */
52 : : static __rte_always_inline void
53 : : __rte_ring_st_set_head_tail(struct rte_ring_headtail *ht, uint32_t tail,
54 : : uint32_t num, uint32_t enqueue)
55 : : {
56 : : uint32_t pos;
57 : :
58 : : RTE_SET_USED(enqueue);
59 : :
60 : 5520 : pos = tail + num;
61 : 5520 : ht->head = pos;
62 : 5520 : rte_atomic_store_explicit(&ht->tail, pos, rte_memory_order_release);
63 : 5520 : }
64 : :
65 : : /**
66 : : * @internal get current tail value.
67 : : * This function should be used only for producer/consumer in MT_HTS mode.
68 : : * Check that user didn't request to move tail above the head.
69 : : * In that situation:
70 : : * - return zero, that will cause abort any pending changes and
71 : : * return head to its previous position.
72 : : * - throw an assert in debug mode.
73 : : */
74 : : static __rte_always_inline uint32_t
75 : : __rte_ring_hts_get_tail(struct rte_ring_hts_headtail *ht, uint32_t *tail,
76 : : uint32_t num)
77 : : {
78 : : uint32_t n;
79 : : union __rte_ring_hts_pos p;
80 : :
81 : 7578 : p.raw = rte_atomic_load_explicit(&ht->ht.raw, rte_memory_order_relaxed);
82 : 5520 : n = p.pos.head - p.pos.tail;
83 : :
84 : : RTE_ASSERT(n >= num);
85 [ - + - + : 6607 : num = (n >= num) ? num : 0;
- + - + -
+ - + - +
- + # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
86 : :
87 : : *tail = p.pos.tail;
88 : : return num;
89 : : }
90 : :
91 : : /**
92 : : * @internal set new values for head and tail as one atomic 64 bit operation.
93 : : * This function should be used only for producer/consumer in MT_HTS mode.
94 : : * Should be used only in conjunction with __rte_ring_hts_get_tail.
95 : : */
96 : : static __rte_always_inline void
97 : : __rte_ring_hts_set_head_tail(struct rte_ring_hts_headtail *ht, uint32_t tail,
98 : : uint32_t num, uint32_t enqueue)
99 : : {
100 : : union __rte_ring_hts_pos p;
101 : :
102 : : RTE_SET_USED(enqueue);
103 : :
104 : 7578 : p.pos.head = tail + num;
105 : 7578 : p.pos.tail = p.pos.head;
106 : :
107 : 7578 : rte_atomic_store_explicit(&ht->ht.raw, p.raw, rte_memory_order_release);
108 : 7578 : }
109 : :
110 : : /**
111 : : * @internal This function moves prod head value.
112 : : */
113 : : static __rte_always_inline unsigned int
114 : : __rte_ring_do_enqueue_start(struct rte_ring *r, uint32_t n,
115 : : enum rte_ring_queue_behavior behavior, uint32_t *free_space)
116 : : {
117 : : uint32_t free, head, next;
118 : :
119 [ # # # ]: 0 : switch (r->prod.sync_type) {
120 : : case RTE_RING_SYNC_ST:
121 : : n = __rte_ring_move_prod_head(r, RTE_RING_SYNC_ST, n,
122 : : behavior, &head, &next, &free);
123 : : break;
124 : : case RTE_RING_SYNC_MT_HTS:
125 : : n = __rte_ring_hts_move_prod_head(r, n, behavior,
126 : : &head, &free);
127 : 0 : break;
128 : : case RTE_RING_SYNC_MT:
129 : : case RTE_RING_SYNC_MT_RTS:
130 : : default:
131 : : /* unsupported mode, shouldn't be here */
132 : : RTE_ASSERT(0);
133 : : n = 0;
134 : : free = 0;
135 : : }
136 : :
137 [ # # ]: 0 : if (free_space != NULL)
138 : 0 : *free_space = free - n;
139 : : return n;
140 : : }
141 : :
142 : : /**
143 : : * @internal This function moves cons head value and copies up to *n*
144 : : * objects from the ring to the user provided obj_table.
145 : : */
146 : : static __rte_always_inline unsigned int
147 : : __rte_ring_do_dequeue_start(struct rte_ring *r, void *obj_table,
148 : : uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
149 : : uint32_t *available)
150 : : {
151 : : uint32_t avail, head, next;
152 : :
153 [ - + - ]: 2073 : switch (r->cons.sync_type) {
154 : : case RTE_RING_SYNC_ST:
155 : : n = __rte_ring_move_cons_head(r, RTE_RING_SYNC_ST, n,
156 : : behavior, &head, &next, &avail);
157 : : break;
158 : : case RTE_RING_SYNC_MT_HTS:
159 : : n = __rte_ring_hts_move_cons_head(r, n, behavior,
160 : : &head, &avail);
161 : 2073 : break;
162 : : case RTE_RING_SYNC_MT:
163 : : case RTE_RING_SYNC_MT_RTS:
164 : : default:
165 : : /* unsupported mode, shouldn't be here */
166 : : RTE_ASSERT(0);
167 : : n = 0;
168 : : avail = 0;
169 : : }
170 : :
171 [ + + ]: 2073 : if (n != 0)
172 : : __rte_ring_dequeue_elems(r, head, obj_table, esize, n);
173 : :
174 [ - + ]: 2073 : if (available != NULL)
175 : 0 : *available = avail - n;
176 : : return n;
177 : : }
178 : :
179 : : #endif /* _RTE_RING_PEEK_ELEM_PVT_H_ */
|