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