xref: /dpdk/lib/stack/rte_stack_lf.h (revision 99a2dd955fba6e4cc23b77d590a033650ced9c45)
1*99a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2*99a2dd95SBruce Richardson  * Copyright(c) 2019 Intel Corporation
3*99a2dd95SBruce Richardson  */
4*99a2dd95SBruce Richardson 
5*99a2dd95SBruce Richardson #ifndef _RTE_STACK_LF_H_
6*99a2dd95SBruce Richardson #define _RTE_STACK_LF_H_
7*99a2dd95SBruce Richardson 
8*99a2dd95SBruce Richardson #if !(defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64))
9*99a2dd95SBruce Richardson #include "rte_stack_lf_stubs.h"
10*99a2dd95SBruce Richardson #else
11*99a2dd95SBruce Richardson #ifdef RTE_USE_C11_MEM_MODEL
12*99a2dd95SBruce Richardson #include "rte_stack_lf_c11.h"
13*99a2dd95SBruce Richardson #else
14*99a2dd95SBruce Richardson #include "rte_stack_lf_generic.h"
15*99a2dd95SBruce Richardson #endif
16*99a2dd95SBruce Richardson #endif
17*99a2dd95SBruce Richardson 
18*99a2dd95SBruce Richardson /**
19*99a2dd95SBruce Richardson  * @internal Push several objects on the lock-free stack (MT-safe).
20*99a2dd95SBruce Richardson  *
21*99a2dd95SBruce Richardson  * @param s
22*99a2dd95SBruce Richardson  *   A pointer to the stack structure.
23*99a2dd95SBruce Richardson  * @param obj_table
24*99a2dd95SBruce Richardson  *   A pointer to a table of void * pointers (objects).
25*99a2dd95SBruce Richardson  * @param n
26*99a2dd95SBruce Richardson  *   The number of objects to push on the stack from the obj_table.
27*99a2dd95SBruce Richardson  * @return
28*99a2dd95SBruce Richardson  *   Actual number of objects enqueued.
29*99a2dd95SBruce Richardson  */
30*99a2dd95SBruce Richardson static __rte_always_inline unsigned int
31*99a2dd95SBruce Richardson __rte_stack_lf_push(struct rte_stack *s,
32*99a2dd95SBruce Richardson 		    void * const *obj_table,
33*99a2dd95SBruce Richardson 		    unsigned int n)
34*99a2dd95SBruce Richardson {
35*99a2dd95SBruce Richardson 	struct rte_stack_lf_elem *tmp, *first, *last = NULL;
36*99a2dd95SBruce Richardson 	unsigned int i;
37*99a2dd95SBruce Richardson 
38*99a2dd95SBruce Richardson 	if (unlikely(n == 0))
39*99a2dd95SBruce Richardson 		return 0;
40*99a2dd95SBruce Richardson 
41*99a2dd95SBruce Richardson 	/* Pop n free elements */
42*99a2dd95SBruce Richardson 	first = __rte_stack_lf_pop_elems(&s->stack_lf.free, n, NULL, &last);
43*99a2dd95SBruce Richardson 	if (unlikely(first == NULL))
44*99a2dd95SBruce Richardson 		return 0;
45*99a2dd95SBruce Richardson 
46*99a2dd95SBruce Richardson 	/* Construct the list elements */
47*99a2dd95SBruce Richardson 	for (tmp = first, i = 0; i < n; i++, tmp = tmp->next)
48*99a2dd95SBruce Richardson 		tmp->data = obj_table[n - i - 1];
49*99a2dd95SBruce Richardson 
50*99a2dd95SBruce Richardson 	/* Push them to the used list */
51*99a2dd95SBruce Richardson 	__rte_stack_lf_push_elems(&s->stack_lf.used, first, last, n);
52*99a2dd95SBruce Richardson 
53*99a2dd95SBruce Richardson 	return n;
54*99a2dd95SBruce Richardson }
55*99a2dd95SBruce Richardson 
56*99a2dd95SBruce Richardson /**
57*99a2dd95SBruce Richardson  * @internal Pop several objects from the lock-free stack (MT-safe).
58*99a2dd95SBruce Richardson  *
59*99a2dd95SBruce Richardson  * @param s
60*99a2dd95SBruce Richardson  *   A pointer to the stack structure.
61*99a2dd95SBruce Richardson  * @param obj_table
62*99a2dd95SBruce Richardson  *   A pointer to a table of void * pointers (objects).
63*99a2dd95SBruce Richardson  * @param n
64*99a2dd95SBruce Richardson  *   The number of objects to pull from the stack.
65*99a2dd95SBruce Richardson  * @return
66*99a2dd95SBruce Richardson  *   - Actual number of objects popped.
67*99a2dd95SBruce Richardson  */
68*99a2dd95SBruce Richardson static __rte_always_inline unsigned int
69*99a2dd95SBruce Richardson __rte_stack_lf_pop(struct rte_stack *s, void **obj_table, unsigned int n)
70*99a2dd95SBruce Richardson {
71*99a2dd95SBruce Richardson 	struct rte_stack_lf_elem *first, *last = NULL;
72*99a2dd95SBruce Richardson 
73*99a2dd95SBruce Richardson 	if (unlikely(n == 0))
74*99a2dd95SBruce Richardson 		return 0;
75*99a2dd95SBruce Richardson 
76*99a2dd95SBruce Richardson 	/* Pop n used elements */
77*99a2dd95SBruce Richardson 	first = __rte_stack_lf_pop_elems(&s->stack_lf.used,
78*99a2dd95SBruce Richardson 					 n, obj_table, &last);
79*99a2dd95SBruce Richardson 	if (unlikely(first == NULL))
80*99a2dd95SBruce Richardson 		return 0;
81*99a2dd95SBruce Richardson 
82*99a2dd95SBruce Richardson 	/* Push the list elements to the free list */
83*99a2dd95SBruce Richardson 	__rte_stack_lf_push_elems(&s->stack_lf.free, first, last, n);
84*99a2dd95SBruce Richardson 
85*99a2dd95SBruce Richardson 	return n;
86*99a2dd95SBruce Richardson }
87*99a2dd95SBruce Richardson 
88*99a2dd95SBruce Richardson /**
89*99a2dd95SBruce Richardson  * @internal Initialize a lock-free stack.
90*99a2dd95SBruce Richardson  *
91*99a2dd95SBruce Richardson  * @param s
92*99a2dd95SBruce Richardson  *   A pointer to the stack structure.
93*99a2dd95SBruce Richardson  * @param count
94*99a2dd95SBruce Richardson  *   The size of the stack.
95*99a2dd95SBruce Richardson  */
96*99a2dd95SBruce Richardson void
97*99a2dd95SBruce Richardson rte_stack_lf_init(struct rte_stack *s, unsigned int count);
98*99a2dd95SBruce Richardson 
99*99a2dd95SBruce Richardson /**
100*99a2dd95SBruce Richardson  * @internal Return the memory required for a lock-free stack.
101*99a2dd95SBruce Richardson  *
102*99a2dd95SBruce Richardson  * @param count
103*99a2dd95SBruce Richardson  *   The size of the stack.
104*99a2dd95SBruce Richardson  * @return
105*99a2dd95SBruce Richardson  *   The bytes to allocate for a lock-free stack.
106*99a2dd95SBruce Richardson  */
107*99a2dd95SBruce Richardson ssize_t
108*99a2dd95SBruce Richardson rte_stack_lf_get_memsize(unsigned int count);
109*99a2dd95SBruce Richardson 
110*99a2dd95SBruce Richardson #endif /* _RTE_STACK_LF_H_ */
111