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