1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2019 Intel Corporation 3 */ 4 5 #ifndef _RTE_STACK_STD_H_ 6 #define _RTE_STACK_STD_H_ 7 8 #include <rte_branch_prediction.h> 9 10 /** 11 * @internal Push several objects on the stack (MT-safe). 12 * 13 * @param s 14 * A pointer to the stack structure. 15 * @param obj_table 16 * A pointer to a table of void * pointers (objects). 17 * @param n 18 * The number of objects to push on the stack from the obj_table. 19 * @return 20 * Actual number of objects pushed (either 0 or *n*). 21 */ 22 __rte_experimental 23 static __rte_always_inline unsigned int 24 __rte_stack_std_push(struct rte_stack *s, void * const *obj_table, 25 unsigned int n) 26 { 27 struct rte_stack_std *stack = &s->stack_std; 28 unsigned int index; 29 void **cache_objs; 30 31 rte_spinlock_lock(&stack->lock); 32 cache_objs = &stack->objs[stack->len]; 33 34 /* Is there sufficient space in the stack? */ 35 if ((stack->len + n) > s->capacity) { 36 rte_spinlock_unlock(&stack->lock); 37 return 0; 38 } 39 40 /* Add elements back into the cache */ 41 for (index = 0; index < n; ++index, obj_table++) 42 cache_objs[index] = *obj_table; 43 44 stack->len += n; 45 46 rte_spinlock_unlock(&stack->lock); 47 return n; 48 } 49 50 /** 51 * @internal Pop several objects from the stack (MT-safe). 52 * 53 * @param s 54 * A pointer to the stack structure. 55 * @param obj_table 56 * A pointer to a table of void * pointers (objects). 57 * @param n 58 * The number of objects to pull from the stack. 59 * @return 60 * Actual number of objects popped (either 0 or *n*). 61 */ 62 __rte_experimental 63 static __rte_always_inline unsigned int 64 __rte_stack_std_pop(struct rte_stack *s, void **obj_table, unsigned int n) 65 { 66 struct rte_stack_std *stack = &s->stack_std; 67 unsigned int index, len; 68 void **cache_objs; 69 70 rte_spinlock_lock(&stack->lock); 71 72 if (unlikely(n > stack->len)) { 73 rte_spinlock_unlock(&stack->lock); 74 return 0; 75 } 76 77 cache_objs = stack->objs; 78 79 for (index = 0, len = stack->len - 1; index < n; 80 ++index, len--, obj_table++) 81 *obj_table = cache_objs[len]; 82 83 stack->len -= n; 84 rte_spinlock_unlock(&stack->lock); 85 86 return n; 87 } 88 89 /** 90 * @internal Return the number of used entries in a stack. 91 * 92 * @param s 93 * A pointer to the stack structure. 94 * @return 95 * The number of used entries in the stack. 96 */ 97 __rte_experimental 98 static __rte_always_inline unsigned int 99 __rte_stack_std_count(struct rte_stack *s) 100 { 101 return (unsigned int)s->stack_std.len; 102 } 103 104 /** 105 * @internal Initialize a standard stack. 106 * 107 * @param s 108 * A pointer to the stack structure. 109 */ 110 void 111 rte_stack_std_init(struct rte_stack *s); 112 113 /** 114 * @internal Return the memory required for a standard stack. 115 * 116 * @param count 117 * The size of the stack. 118 * @return 119 * The bytes to allocate for a standard stack. 120 */ 121 ssize_t 122 rte_stack_std_get_memsize(unsigned int count); 123 124 #endif /* _RTE_STACK_STD_H_ */ 125