DPDK 26.11.0-rc2
rte_stack_lf.h
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019 Intel Corporation
3 */
4
5#ifndef _RTE_STACK_LF_H_
6#define _RTE_STACK_LF_H_
7
8#if !(defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64))
9#include "rte_stack_lf_stubs.h"
10#else
11#include "rte_stack_lf_c11.h"
12
16#define RTE_STACK_LF_SUPPORTED
17#endif
18
19static __rte_always_inline unsigned int
20__rte_stack_lf_count(struct rte_stack *s)
21{
22 /* stack_lf_push() and stack_lf_pop() do not update the list's contents
23 * and stack_lf->len atomically, which can cause the list to appear
24 * shorter than it actually is if this function is called while other
25 * threads are modifying the list.
26 *
27 * However, given the inherently approximate nature of the get_count
28 * callback -- even if the list and its size were updated atomically,
29 * the size could change between when get_count executes and when the
30 * value is returned to the caller -- this is acceptable.
31 *
32 * The stack_lf->len updates are placed such that the list may appear to
33 * have fewer elements than it does, but will never appear to have more
34 * elements. If the mempool is near-empty to the point that this is a
35 * concern, the user should consider increasing the mempool size.
36 */
37 return __rte_stack_lf_elems_count(&s->stack_lf.used);
38}
39
52static __rte_always_inline unsigned int
53__rte_stack_lf_push(struct rte_stack *s,
54 void * const *obj_table,
55 unsigned int n)
56{
57 struct rte_stack_lf_elem *tmp, *first, *last = NULL;
58 unsigned int i;
59
60 if (unlikely(n == 0))
61 return 0;
62
63 /* Pop n free elements */
64 first = __rte_stack_lf_pop_elems(&s->stack_lf.free, n, NULL, &last);
65 if (unlikely(first == NULL))
66 return 0;
67
68 /* Construct the list elements */
69 for (tmp = first, i = 0; i < n; i++, tmp = tmp->next)
70 tmp->data = obj_table[n - i - 1];
71
72 /* Push them to the used list */
73 __rte_stack_lf_push_elems(&s->stack_lf.used, first, last, n);
74
75 return n;
76}
77
90static __rte_always_inline unsigned int
91__rte_stack_lf_pop(struct rte_stack *s, void **obj_table, unsigned int n)
92{
93 struct rte_stack_lf_elem *first, *last = NULL;
94
95 if (unlikely(n == 0))
96 return 0;
97
98 /* Pop n used elements */
99 __rte_assume(obj_table != NULL);
100 first = __rte_stack_lf_pop_elems(&s->stack_lf.used,
101 n, obj_table, &last);
102 if (unlikely(first == NULL))
103 return 0;
104
105 /* Push the list elements to the free list */
106 __rte_stack_lf_push_elems(&s->stack_lf.free, first, last, n);
107
108 return n;
109}
110
119void
120rte_stack_lf_init(struct rte_stack *s, unsigned int count);
121
130ssize_t
131rte_stack_lf_get_memsize(unsigned int count);
132
133#endif /* _RTE_STACK_LF_H_ */
#define unlikely(x)
#define __rte_assume(condition)
Definition: rte_common.h:595
#define __rte_always_inline
Definition: rte_common.h:534