xref: /dpdk/drivers/mempool/stack/rte_mempool_stack.c (revision 5566a3e35866ce9e5eacf886c27b460ebfcd6ee9)
1*5566a3e3SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2*5566a3e3SBruce Richardson  * Copyright(c) 2016 Intel Corporation
31263b426SShreyansh Jain  */
41263b426SShreyansh Jain 
51263b426SShreyansh Jain #include <stdio.h>
61263b426SShreyansh Jain #include <rte_mempool.h>
71263b426SShreyansh Jain #include <rte_malloc.h>
81263b426SShreyansh Jain 
91263b426SShreyansh Jain struct rte_mempool_stack {
101263b426SShreyansh Jain 	rte_spinlock_t sl;
111263b426SShreyansh Jain 
121263b426SShreyansh Jain 	uint32_t size;
131263b426SShreyansh Jain 	uint32_t len;
141263b426SShreyansh Jain 	void *objs[];
151263b426SShreyansh Jain };
161263b426SShreyansh Jain 
171263b426SShreyansh Jain static int
181263b426SShreyansh Jain stack_alloc(struct rte_mempool *mp)
191263b426SShreyansh Jain {
201263b426SShreyansh Jain 	struct rte_mempool_stack *s;
211263b426SShreyansh Jain 	unsigned n = mp->size;
221263b426SShreyansh Jain 	int size = sizeof(*s) + (n+16)*sizeof(void *);
231263b426SShreyansh Jain 
241263b426SShreyansh Jain 	/* Allocate our local memory structure */
251263b426SShreyansh Jain 	s = rte_zmalloc_socket("mempool-stack",
261263b426SShreyansh Jain 			size,
271263b426SShreyansh Jain 			RTE_CACHE_LINE_SIZE,
281263b426SShreyansh Jain 			mp->socket_id);
291263b426SShreyansh Jain 	if (s == NULL) {
301263b426SShreyansh Jain 		RTE_LOG(ERR, MEMPOOL, "Cannot allocate stack!\n");
311263b426SShreyansh Jain 		return -ENOMEM;
321263b426SShreyansh Jain 	}
331263b426SShreyansh Jain 
341263b426SShreyansh Jain 	rte_spinlock_init(&s->sl);
351263b426SShreyansh Jain 
361263b426SShreyansh Jain 	s->size = n;
371263b426SShreyansh Jain 	mp->pool_data = s;
381263b426SShreyansh Jain 
391263b426SShreyansh Jain 	return 0;
401263b426SShreyansh Jain }
411263b426SShreyansh Jain 
421263b426SShreyansh Jain static int
431263b426SShreyansh Jain stack_enqueue(struct rte_mempool *mp, void * const *obj_table,
441263b426SShreyansh Jain 		unsigned n)
451263b426SShreyansh Jain {
461263b426SShreyansh Jain 	struct rte_mempool_stack *s = mp->pool_data;
471263b426SShreyansh Jain 	void **cache_objs;
481263b426SShreyansh Jain 	unsigned index;
491263b426SShreyansh Jain 
501263b426SShreyansh Jain 	rte_spinlock_lock(&s->sl);
511263b426SShreyansh Jain 	cache_objs = &s->objs[s->len];
521263b426SShreyansh Jain 
531263b426SShreyansh Jain 	/* Is there sufficient space in the stack ? */
541263b426SShreyansh Jain 	if ((s->len + n) > s->size) {
551263b426SShreyansh Jain 		rte_spinlock_unlock(&s->sl);
561263b426SShreyansh Jain 		return -ENOBUFS;
571263b426SShreyansh Jain 	}
581263b426SShreyansh Jain 
591263b426SShreyansh Jain 	/* Add elements back into the cache */
601263b426SShreyansh Jain 	for (index = 0; index < n; ++index, obj_table++)
611263b426SShreyansh Jain 		cache_objs[index] = *obj_table;
621263b426SShreyansh Jain 
631263b426SShreyansh Jain 	s->len += n;
641263b426SShreyansh Jain 
651263b426SShreyansh Jain 	rte_spinlock_unlock(&s->sl);
661263b426SShreyansh Jain 	return 0;
671263b426SShreyansh Jain }
681263b426SShreyansh Jain 
691263b426SShreyansh Jain static int
701263b426SShreyansh Jain stack_dequeue(struct rte_mempool *mp, void **obj_table,
711263b426SShreyansh Jain 		unsigned n)
721263b426SShreyansh Jain {
731263b426SShreyansh Jain 	struct rte_mempool_stack *s = mp->pool_data;
741263b426SShreyansh Jain 	void **cache_objs;
751263b426SShreyansh Jain 	unsigned index, len;
761263b426SShreyansh Jain 
771263b426SShreyansh Jain 	rte_spinlock_lock(&s->sl);
781263b426SShreyansh Jain 
791263b426SShreyansh Jain 	if (unlikely(n > s->len)) {
801263b426SShreyansh Jain 		rte_spinlock_unlock(&s->sl);
811263b426SShreyansh Jain 		return -ENOENT;
821263b426SShreyansh Jain 	}
831263b426SShreyansh Jain 
841263b426SShreyansh Jain 	cache_objs = s->objs;
851263b426SShreyansh Jain 
861263b426SShreyansh Jain 	for (index = 0, len = s->len - 1; index < n;
871263b426SShreyansh Jain 			++index, len--, obj_table++)
881263b426SShreyansh Jain 		*obj_table = cache_objs[len];
891263b426SShreyansh Jain 
901263b426SShreyansh Jain 	s->len -= n;
911263b426SShreyansh Jain 	rte_spinlock_unlock(&s->sl);
921263b426SShreyansh Jain 	return 0;
931263b426SShreyansh Jain }
941263b426SShreyansh Jain 
951263b426SShreyansh Jain static unsigned
961263b426SShreyansh Jain stack_get_count(const struct rte_mempool *mp)
971263b426SShreyansh Jain {
981263b426SShreyansh Jain 	struct rte_mempool_stack *s = mp->pool_data;
991263b426SShreyansh Jain 
1001263b426SShreyansh Jain 	return s->len;
1011263b426SShreyansh Jain }
1021263b426SShreyansh Jain 
1031263b426SShreyansh Jain static void
1041263b426SShreyansh Jain stack_free(struct rte_mempool *mp)
1051263b426SShreyansh Jain {
1061263b426SShreyansh Jain 	rte_free((void *)(mp->pool_data));
1071263b426SShreyansh Jain }
1081263b426SShreyansh Jain 
1091263b426SShreyansh Jain static struct rte_mempool_ops ops_stack = {
1101263b426SShreyansh Jain 	.name = "stack",
1111263b426SShreyansh Jain 	.alloc = stack_alloc,
1121263b426SShreyansh Jain 	.free = stack_free,
1131263b426SShreyansh Jain 	.enqueue = stack_enqueue,
1141263b426SShreyansh Jain 	.dequeue = stack_dequeue,
1151263b426SShreyansh Jain 	.get_count = stack_get_count
1161263b426SShreyansh Jain };
1171263b426SShreyansh Jain 
1181263b426SShreyansh Jain MEMPOOL_REGISTER_OPS(ops_stack);
119