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_ */ 116