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