test/mbuf: fix access to freed memory
[dpdk.git] / lib / stack / 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 #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
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
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_ */