xref: /dpdk/lib/stack/rte_stack_std.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_STD_H_
6*99a2dd95SBruce Richardson #define _RTE_STACK_STD_H_
7*99a2dd95SBruce Richardson 
8*99a2dd95SBruce Richardson #include <rte_branch_prediction.h>
9*99a2dd95SBruce Richardson 
10*99a2dd95SBruce Richardson /**
11*99a2dd95SBruce Richardson  * @internal Push several objects on the stack (MT-safe).
12*99a2dd95SBruce Richardson  *
13*99a2dd95SBruce Richardson  * @param s
14*99a2dd95SBruce Richardson  *   A pointer to the stack structure.
15*99a2dd95SBruce Richardson  * @param obj_table
16*99a2dd95SBruce Richardson  *   A pointer to a table of void * pointers (objects).
17*99a2dd95SBruce Richardson  * @param n
18*99a2dd95SBruce Richardson  *   The number of objects to push on the stack from the obj_table.
19*99a2dd95SBruce Richardson  * @return
20*99a2dd95SBruce Richardson  *   Actual number of objects pushed (either 0 or *n*).
21*99a2dd95SBruce Richardson  */
22*99a2dd95SBruce Richardson static __rte_always_inline unsigned int
__rte_stack_std_push(struct rte_stack * s,void * const * obj_table,unsigned int n)23*99a2dd95SBruce Richardson __rte_stack_std_push(struct rte_stack *s, void * const *obj_table,
24*99a2dd95SBruce Richardson 		     unsigned int n)
25*99a2dd95SBruce Richardson {
26*99a2dd95SBruce Richardson 	struct rte_stack_std *stack = &s->stack_std;
27*99a2dd95SBruce Richardson 	unsigned int index;
28*99a2dd95SBruce Richardson 	void **cache_objs;
29*99a2dd95SBruce Richardson 
30*99a2dd95SBruce Richardson 	rte_spinlock_lock(&stack->lock);
31*99a2dd95SBruce Richardson 	cache_objs = &stack->objs[stack->len];
32*99a2dd95SBruce Richardson 
33*99a2dd95SBruce Richardson 	/* Is there sufficient space in the stack? */
34*99a2dd95SBruce Richardson 	if ((stack->len + n) > s->capacity) {
35*99a2dd95SBruce Richardson 		rte_spinlock_unlock(&stack->lock);
36*99a2dd95SBruce Richardson 		return 0;
37*99a2dd95SBruce Richardson 	}
38*99a2dd95SBruce Richardson 
39*99a2dd95SBruce Richardson 	/* Add elements back into the cache */
40*99a2dd95SBruce Richardson 	for (index = 0; index < n; ++index, obj_table++)
41*99a2dd95SBruce Richardson 		cache_objs[index] = *obj_table;
42*99a2dd95SBruce Richardson 
43*99a2dd95SBruce Richardson 	stack->len += n;
44*99a2dd95SBruce Richardson 
45*99a2dd95SBruce Richardson 	rte_spinlock_unlock(&stack->lock);
46*99a2dd95SBruce Richardson 	return n;
47*99a2dd95SBruce Richardson }
48*99a2dd95SBruce Richardson 
49*99a2dd95SBruce Richardson /**
50*99a2dd95SBruce Richardson  * @internal Pop several objects from the stack (MT-safe).
51*99a2dd95SBruce Richardson  *
52*99a2dd95SBruce Richardson  * @param s
53*99a2dd95SBruce Richardson  *   A pointer to the stack structure.
54*99a2dd95SBruce Richardson  * @param obj_table
55*99a2dd95SBruce Richardson  *   A pointer to a table of void * pointers (objects).
56*99a2dd95SBruce Richardson  * @param n
57*99a2dd95SBruce Richardson  *   The number of objects to pull from the stack.
58*99a2dd95SBruce Richardson  * @return
59*99a2dd95SBruce Richardson  *   Actual number of objects popped (either 0 or *n*).
60*99a2dd95SBruce Richardson  */
61*99a2dd95SBruce Richardson static __rte_always_inline unsigned int
__rte_stack_std_pop(struct rte_stack * s,void ** obj_table,unsigned int n)62*99a2dd95SBruce Richardson __rte_stack_std_pop(struct rte_stack *s, void **obj_table, unsigned int n)
63*99a2dd95SBruce Richardson {
64*99a2dd95SBruce Richardson 	struct rte_stack_std *stack = &s->stack_std;
65*99a2dd95SBruce Richardson 	unsigned int index, len;
66*99a2dd95SBruce Richardson 	void **cache_objs;
67*99a2dd95SBruce Richardson 
68*99a2dd95SBruce Richardson 	rte_spinlock_lock(&stack->lock);
69*99a2dd95SBruce Richardson 
70*99a2dd95SBruce Richardson 	if (unlikely(n > stack->len)) {
71*99a2dd95SBruce Richardson 		rte_spinlock_unlock(&stack->lock);
72*99a2dd95SBruce Richardson 		return 0;
73*99a2dd95SBruce Richardson 	}
74*99a2dd95SBruce Richardson 
75*99a2dd95SBruce Richardson 	cache_objs = stack->objs;
76*99a2dd95SBruce Richardson 
77*99a2dd95SBruce Richardson 	for (index = 0, len = stack->len - 1; index < n;
78*99a2dd95SBruce Richardson 			++index, len--, obj_table++)
79*99a2dd95SBruce Richardson 		*obj_table = cache_objs[len];
80*99a2dd95SBruce Richardson 
81*99a2dd95SBruce Richardson 	stack->len -= n;
82*99a2dd95SBruce Richardson 	rte_spinlock_unlock(&stack->lock);
83*99a2dd95SBruce Richardson 
84*99a2dd95SBruce Richardson 	return n;
85*99a2dd95SBruce Richardson }
86*99a2dd95SBruce Richardson 
87*99a2dd95SBruce Richardson /**
88*99a2dd95SBruce Richardson  * @internal Return the number of used entries in a stack.
89*99a2dd95SBruce Richardson  *
90*99a2dd95SBruce Richardson  * @param s
91*99a2dd95SBruce Richardson  *   A pointer to the stack structure.
92*99a2dd95SBruce Richardson  * @return
93*99a2dd95SBruce Richardson  *   The number of used entries in the stack.
94*99a2dd95SBruce Richardson  */
95*99a2dd95SBruce Richardson static __rte_always_inline unsigned int
__rte_stack_std_count(struct rte_stack * s)96*99a2dd95SBruce Richardson __rte_stack_std_count(struct rte_stack *s)
97*99a2dd95SBruce Richardson {
98*99a2dd95SBruce Richardson 	return (unsigned int)s->stack_std.len;
99*99a2dd95SBruce Richardson }
100*99a2dd95SBruce Richardson 
101*99a2dd95SBruce Richardson /**
102*99a2dd95SBruce Richardson  * @internal Initialize a standard stack.
103*99a2dd95SBruce Richardson  *
104*99a2dd95SBruce Richardson  * @param s
105*99a2dd95SBruce Richardson  *   A pointer to the stack structure.
106*99a2dd95SBruce Richardson  */
107*99a2dd95SBruce Richardson void
108*99a2dd95SBruce Richardson rte_stack_std_init(struct rte_stack *s);
109*99a2dd95SBruce Richardson 
110*99a2dd95SBruce Richardson /**
111*99a2dd95SBruce Richardson  * @internal Return the memory required for a standard stack.
112*99a2dd95SBruce Richardson  *
113*99a2dd95SBruce Richardson  * @param count
114*99a2dd95SBruce Richardson  *   The size of the stack.
115*99a2dd95SBruce Richardson  * @return
116*99a2dd95SBruce Richardson  *   The bytes to allocate for a standard stack.
117*99a2dd95SBruce Richardson  */
118*99a2dd95SBruce Richardson ssize_t
119*99a2dd95SBruce Richardson rte_stack_std_get_memsize(unsigned int count);
120*99a2dd95SBruce Richardson 
121*99a2dd95SBruce Richardson #endif /* _RTE_STACK_STD_H_ */
122