199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2019 Intel Corporation
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson
599a2dd95SBruce Richardson #ifndef _RTE_STACK_LF_H_
699a2dd95SBruce Richardson #define _RTE_STACK_LF_H_
799a2dd95SBruce Richardson
899a2dd95SBruce Richardson #if !(defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_ARM64))
999a2dd95SBruce Richardson #include "rte_stack_lf_stubs.h"
1099a2dd95SBruce Richardson #else
1199a2dd95SBruce Richardson #ifdef RTE_USE_C11_MEM_MODEL
1299a2dd95SBruce Richardson #include "rte_stack_lf_c11.h"
1399a2dd95SBruce Richardson #else
1499a2dd95SBruce Richardson #include "rte_stack_lf_generic.h"
1599a2dd95SBruce Richardson #endif
16*1abb185dSStanislaw Kardach
17*1abb185dSStanislaw Kardach /**
18*1abb185dSStanislaw Kardach * Indicates that RTE_STACK_F_LF is supported.
19*1abb185dSStanislaw Kardach */
20*1abb185dSStanislaw Kardach #define RTE_STACK_LF_SUPPORTED
2199a2dd95SBruce Richardson #endif
2299a2dd95SBruce Richardson
2399a2dd95SBruce Richardson /**
2499a2dd95SBruce Richardson * @internal Push several objects on the lock-free stack (MT-safe).
2599a2dd95SBruce Richardson *
2699a2dd95SBruce Richardson * @param s
2799a2dd95SBruce Richardson * A pointer to the stack structure.
2899a2dd95SBruce Richardson * @param obj_table
2999a2dd95SBruce Richardson * A pointer to a table of void * pointers (objects).
3099a2dd95SBruce Richardson * @param n
3199a2dd95SBruce Richardson * The number of objects to push on the stack from the obj_table.
3299a2dd95SBruce Richardson * @return
3399a2dd95SBruce Richardson * Actual number of objects enqueued.
3499a2dd95SBruce Richardson */
3599a2dd95SBruce Richardson static __rte_always_inline unsigned int
__rte_stack_lf_push(struct rte_stack * s,void * const * obj_table,unsigned int n)3699a2dd95SBruce Richardson __rte_stack_lf_push(struct rte_stack *s,
3799a2dd95SBruce Richardson void * const *obj_table,
3899a2dd95SBruce Richardson unsigned int n)
3999a2dd95SBruce Richardson {
4099a2dd95SBruce Richardson struct rte_stack_lf_elem *tmp, *first, *last = NULL;
4199a2dd95SBruce Richardson unsigned int i;
4299a2dd95SBruce Richardson
4399a2dd95SBruce Richardson if (unlikely(n == 0))
4499a2dd95SBruce Richardson return 0;
4599a2dd95SBruce Richardson
4699a2dd95SBruce Richardson /* Pop n free elements */
4799a2dd95SBruce Richardson first = __rte_stack_lf_pop_elems(&s->stack_lf.free, n, NULL, &last);
4899a2dd95SBruce Richardson if (unlikely(first == NULL))
4999a2dd95SBruce Richardson return 0;
5099a2dd95SBruce Richardson
5199a2dd95SBruce Richardson /* Construct the list elements */
5299a2dd95SBruce Richardson for (tmp = first, i = 0; i < n; i++, tmp = tmp->next)
5399a2dd95SBruce Richardson tmp->data = obj_table[n - i - 1];
5499a2dd95SBruce Richardson
5599a2dd95SBruce Richardson /* Push them to the used list */
5699a2dd95SBruce Richardson __rte_stack_lf_push_elems(&s->stack_lf.used, first, last, n);
5799a2dd95SBruce Richardson
5899a2dd95SBruce Richardson return n;
5999a2dd95SBruce Richardson }
6099a2dd95SBruce Richardson
6199a2dd95SBruce Richardson /**
6299a2dd95SBruce Richardson * @internal Pop several objects from the lock-free stack (MT-safe).
6399a2dd95SBruce Richardson *
6499a2dd95SBruce Richardson * @param s
6599a2dd95SBruce Richardson * A pointer to the stack structure.
6699a2dd95SBruce Richardson * @param obj_table
6799a2dd95SBruce Richardson * A pointer to a table of void * pointers (objects).
6899a2dd95SBruce Richardson * @param n
6999a2dd95SBruce Richardson * The number of objects to pull from the stack.
7099a2dd95SBruce Richardson * @return
7199a2dd95SBruce Richardson * - Actual number of objects popped.
7299a2dd95SBruce Richardson */
7399a2dd95SBruce Richardson static __rte_always_inline unsigned int
__rte_stack_lf_pop(struct rte_stack * s,void ** obj_table,unsigned int n)7499a2dd95SBruce Richardson __rte_stack_lf_pop(struct rte_stack *s, void **obj_table, unsigned int n)
7599a2dd95SBruce Richardson {
7699a2dd95SBruce Richardson struct rte_stack_lf_elem *first, *last = NULL;
7799a2dd95SBruce Richardson
7899a2dd95SBruce Richardson if (unlikely(n == 0))
7999a2dd95SBruce Richardson return 0;
8099a2dd95SBruce Richardson
8199a2dd95SBruce Richardson /* Pop n used elements */
8299a2dd95SBruce Richardson first = __rte_stack_lf_pop_elems(&s->stack_lf.used,
8399a2dd95SBruce Richardson n, obj_table, &last);
8499a2dd95SBruce Richardson if (unlikely(first == NULL))
8599a2dd95SBruce Richardson return 0;
8699a2dd95SBruce Richardson
8799a2dd95SBruce Richardson /* Push the list elements to the free list */
8899a2dd95SBruce Richardson __rte_stack_lf_push_elems(&s->stack_lf.free, first, last, n);
8999a2dd95SBruce Richardson
9099a2dd95SBruce Richardson return n;
9199a2dd95SBruce Richardson }
9299a2dd95SBruce Richardson
9399a2dd95SBruce Richardson /**
9499a2dd95SBruce Richardson * @internal Initialize a lock-free stack.
9599a2dd95SBruce Richardson *
9699a2dd95SBruce Richardson * @param s
9799a2dd95SBruce Richardson * A pointer to the stack structure.
9899a2dd95SBruce Richardson * @param count
9999a2dd95SBruce Richardson * The size of the stack.
10099a2dd95SBruce Richardson */
10199a2dd95SBruce Richardson void
10299a2dd95SBruce Richardson rte_stack_lf_init(struct rte_stack *s, unsigned int count);
10399a2dd95SBruce Richardson
10499a2dd95SBruce Richardson /**
10599a2dd95SBruce Richardson * @internal Return the memory required for a lock-free stack.
10699a2dd95SBruce Richardson *
10799a2dd95SBruce Richardson * @param count
10899a2dd95SBruce Richardson * The size of the stack.
10999a2dd95SBruce Richardson * @return
11099a2dd95SBruce Richardson * The bytes to allocate for a lock-free stack.
11199a2dd95SBruce Richardson */
11299a2dd95SBruce Richardson ssize_t
11399a2dd95SBruce Richardson rte_stack_lf_get_memsize(unsigned int count);
11499a2dd95SBruce Richardson
11599a2dd95SBruce Richardson #endif /* _RTE_STACK_LF_H_ */
116