5#ifndef _RTE_STACK_PILE_H_
6#define _RTE_STACK_PILE_H_
10#include "rte_stack_lf.h"
11#ifdef RTE_STACK_LF_SUPPORTED
15#define RTE_STACK_PILE_SUPPORTED
19__rte_stack_pile_count(
struct rte_stack *s)
36 return RTE_MIN((
unsigned int)s->capacity,
37 __rte_stack_lf_elems_count(&s->stack_pile.bulk) * RTE_STACK_PILE_BULK_SIZE +
38 __rte_stack_lf_elems_count(&s->stack_pile.solo));
42__rte_stack_pile_bulk_push_elems(
struct rte_stack_lf_list *list,
43 struct rte_stack_pile_bulk_elem *first,
44 struct rte_stack_pile_bulk_elem *last,
47 __rte_stack_lf_push_elems(list,
48 (
struct rte_stack_lf_elem *)first,
49 (
struct rte_stack_lf_elem *)last,
54__rte_stack_pile_bulk_pop_elems(
struct rte_stack_lf_list *list,
57 struct rte_stack_pile_bulk_elem **last)
59 struct rte_stack_lf_elem *first =
60 __rte_stack_lf_pop_elems(list, num, NULL,
61 (
struct rte_stack_lf_elem **)last);
65 if (obj_table != NULL) {
73 struct rte_stack_lf_elem *tmp = first;
74 for (
unsigned int i = 0; i < num; i++, tmp = tmp->next)
75 rte_memcpy(&obj_table[i * RTE_STACK_PILE_BULK_SIZE],
76 ((
struct rte_stack_pile_bulk_elem *)tmp)->objs,
77 sizeof(
void *) * RTE_STACK_PILE_BULK_SIZE);
80 return (
struct rte_stack_pile_bulk_elem *)first;
96__rte_stack_pile_push(
struct rte_stack *s,
97 void *
const *obj_table,
100 RTE_ASSERT(s != NULL);
101 RTE_ASSERT(obj_table != NULL);
103 struct rte_stack_pile *pile = &s->stack_pile;
104 struct rte_stack_pile_bulk_elem *bulk_first = NULL, *bulk_last = NULL;
105 struct rte_stack_lf_elem *solo_first = NULL, *solo_last = NULL;
106 struct rte_stack_lf_elem *tmp;
107 unsigned int n_bulk = n / RTE_STACK_PILE_BULK_SIZE;
108 unsigned int n_solo = n & (RTE_STACK_PILE_BULK_SIZE - 1);
118 bulk_first = __rte_stack_pile_bulk_pop_elems(&pile->free_bulk, n_bulk, NULL, &bulk_last);
127 solo_first = __rte_stack_lf_pop_elems(&pile->free_solo, n_solo, NULL, &solo_last);
131 __rte_stack_pile_bulk_push_elems(&pile->free_bulk,
132 bulk_first, bulk_last, n_bulk);
143 for (i = 0; i < n_solo; i++, tmp = tmp->next)
144 tmp->data = obj_table[n_bulk * RTE_STACK_PILE_BULK_SIZE + n_solo - i - 1];
147 __rte_stack_lf_push_elems(&pile->solo, solo_first, solo_last, n_solo);
157 tmp = (
struct rte_stack_lf_elem *)bulk_first;
159 for (i = 0; i < n_bulk; i++, tmp = tmp->next)
160 rte_memcpy(((
struct rte_stack_pile_bulk_elem *)tmp)->objs,
161 &obj_table[(n_bulk - i - 1) * RTE_STACK_PILE_BULK_SIZE],
162 sizeof(
void *) * RTE_STACK_PILE_BULK_SIZE);
165 __rte_stack_pile_bulk_push_elems(&pile->bulk, bulk_first, bulk_last, n_bulk);
184__rte_stack_pile_pop_frag(
struct rte_stack_pile *
const pile,
188 alignas(RTE_CACHE_LINE_SIZE)
void *obj_frag[RTE_STACK_PILE_BULK_SIZE];
189 struct rte_stack_pile_bulk_elem *frag = NULL;
190 struct rte_stack_lf_elem *solo_first = NULL, *solo_last = NULL, *tmp;
194 RTE_ASSERT(n < RTE_STACK_PILE_BULK_SIZE);
197 frag = __rte_stack_pile_bulk_pop_elems(&pile->bulk, 1, obj_frag, NULL);
204 for (i = 0; i < n; i++)
205 obj_table[i] = obj_frag[i];
209 __rte_assume(RTE_STACK_PILE_BULK_SIZE - n < RTE_STACK_PILE_BULK_SIZE);
210 solo_first = __rte_stack_lf_pop_elems(&pile->free_solo,
211 RTE_STACK_PILE_BULK_SIZE - n, NULL, &solo_last);
219 __rte_stack_pile_bulk_push_elems(&pile->bulk, frag, frag, 1);
227 for (i = n; i < RTE_STACK_PILE_BULK_SIZE; i++, tmp = tmp->next)
228 tmp->data = obj_frag[i];
231 __rte_stack_lf_push_elems(&pile->solo, solo_first, solo_last,
232 RTE_STACK_PILE_BULK_SIZE - n);
235 __rte_stack_pile_bulk_push_elems(&pile->free_bulk, frag, frag, 1);
253__rte_stack_pile_pop(
struct rte_stack *s,
257 RTE_ASSERT(s != NULL);
258 RTE_ASSERT(obj_table != NULL);
260 struct rte_stack_pile *pile = &s->stack_pile;
261 struct rte_stack_pile_bulk_elem *bulk_first = NULL, *bulk_last = NULL;
262 struct rte_stack_lf_elem *solo_first = NULL, *solo_last = NULL;
263 unsigned int n_bulk = n / RTE_STACK_PILE_BULK_SIZE;
264 unsigned int n_solo = n & (RTE_STACK_PILE_BULK_SIZE - 1);
274 bulk_first = __rte_stack_pile_bulk_pop_elems(&pile->bulk, n_bulk, obj_table, &bulk_last);
282 unsigned int delta_bulk = n_bulk - __rte_stack_lf_elems_count(&pile->bulk);
284 if (
unlikely((
int)delta_bulk <= 0)) {
292 n_bulk -= delta_bulk;
293 n_solo += RTE_STACK_PILE_BULK_SIZE * delta_bulk;
301 obj_table += n_bulk * RTE_STACK_PILE_BULK_SIZE;
308 solo_first = __rte_stack_lf_pop_elems(&pile->solo, n_solo,
309 obj_table, &solo_last);
310 if (solo_first != NULL)
314 if (
unlikely(n_solo >= RTE_STACK_PILE_BULK_SIZE))
317 if (
unlikely(__rte_stack_pile_pop_frag(pile, obj_table, n_solo) == 0))
322 if (bulk_first != NULL)
323 __rte_stack_pile_bulk_push_elems(&pile->free_bulk, bulk_first, bulk_last, n_bulk);
324 if (solo_first != NULL)
325 __rte_stack_lf_push_elems(&pile->free_solo, solo_first, solo_last, n_solo);
331 if (bulk_first != NULL)
332 __rte_stack_pile_bulk_push_elems(&pile->bulk, bulk_first, bulk_last, n_bulk);
346rte_stack_pile_init(
struct rte_stack *s,
unsigned int count);
357rte_stack_pile_get_memsize(
unsigned int count);
#define __rte_assume(condition)
#define __rte_always_inline
static void * rte_memcpy(void *dst, const void *src, size_t n)