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