1*d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*d30ea906Sjfb8856606  * Copyright(c) 2016 Intel Corporation
32bfe3f2eSlogwang  */
42bfe3f2eSlogwang 
52bfe3f2eSlogwang #include <stdio.h>
62bfe3f2eSlogwang #include <rte_mempool.h>
72bfe3f2eSlogwang #include <rte_malloc.h>
82bfe3f2eSlogwang 
92bfe3f2eSlogwang struct rte_mempool_stack {
102bfe3f2eSlogwang 	rte_spinlock_t sl;
112bfe3f2eSlogwang 
122bfe3f2eSlogwang 	uint32_t size;
132bfe3f2eSlogwang 	uint32_t len;
142bfe3f2eSlogwang 	void *objs[];
152bfe3f2eSlogwang };
162bfe3f2eSlogwang 
172bfe3f2eSlogwang static int
182bfe3f2eSlogwang stack_alloc(struct rte_mempool *mp)
192bfe3f2eSlogwang {
202bfe3f2eSlogwang 	struct rte_mempool_stack *s;
212bfe3f2eSlogwang 	unsigned n = mp->size;
222bfe3f2eSlogwang 	int size = sizeof(*s) + (n+16)*sizeof(void *);
232bfe3f2eSlogwang 
242bfe3f2eSlogwang 	/* Allocate our local memory structure */
252bfe3f2eSlogwang 	s = rte_zmalloc_socket("mempool-stack",
262bfe3f2eSlogwang 			size,
272bfe3f2eSlogwang 			RTE_CACHE_LINE_SIZE,
282bfe3f2eSlogwang 			mp->socket_id);
292bfe3f2eSlogwang 	if (s == NULL) {
302bfe3f2eSlogwang 		RTE_LOG(ERR, MEMPOOL, "Cannot allocate stack!\n");
312bfe3f2eSlogwang 		return -ENOMEM;
322bfe3f2eSlogwang 	}
332bfe3f2eSlogwang 
342bfe3f2eSlogwang 	rte_spinlock_init(&s->sl);
352bfe3f2eSlogwang 
362bfe3f2eSlogwang 	s->size = n;
372bfe3f2eSlogwang 	mp->pool_data = s;
382bfe3f2eSlogwang 
392bfe3f2eSlogwang 	return 0;
402bfe3f2eSlogwang }
412bfe3f2eSlogwang 
422bfe3f2eSlogwang static int
432bfe3f2eSlogwang stack_enqueue(struct rte_mempool *mp, void * const *obj_table,
442bfe3f2eSlogwang 		unsigned n)
452bfe3f2eSlogwang {
462bfe3f2eSlogwang 	struct rte_mempool_stack *s = mp->pool_data;
472bfe3f2eSlogwang 	void **cache_objs;
482bfe3f2eSlogwang 	unsigned index;
492bfe3f2eSlogwang 
502bfe3f2eSlogwang 	rte_spinlock_lock(&s->sl);
512bfe3f2eSlogwang 	cache_objs = &s->objs[s->len];
522bfe3f2eSlogwang 
532bfe3f2eSlogwang 	/* Is there sufficient space in the stack ? */
542bfe3f2eSlogwang 	if ((s->len + n) > s->size) {
552bfe3f2eSlogwang 		rte_spinlock_unlock(&s->sl);
562bfe3f2eSlogwang 		return -ENOBUFS;
572bfe3f2eSlogwang 	}
582bfe3f2eSlogwang 
592bfe3f2eSlogwang 	/* Add elements back into the cache */
602bfe3f2eSlogwang 	for (index = 0; index < n; ++index, obj_table++)
612bfe3f2eSlogwang 		cache_objs[index] = *obj_table;
622bfe3f2eSlogwang 
632bfe3f2eSlogwang 	s->len += n;
642bfe3f2eSlogwang 
652bfe3f2eSlogwang 	rte_spinlock_unlock(&s->sl);
662bfe3f2eSlogwang 	return 0;
672bfe3f2eSlogwang }
682bfe3f2eSlogwang 
692bfe3f2eSlogwang static int
702bfe3f2eSlogwang stack_dequeue(struct rte_mempool *mp, void **obj_table,
712bfe3f2eSlogwang 		unsigned n)
722bfe3f2eSlogwang {
732bfe3f2eSlogwang 	struct rte_mempool_stack *s = mp->pool_data;
742bfe3f2eSlogwang 	void **cache_objs;
752bfe3f2eSlogwang 	unsigned index, len;
762bfe3f2eSlogwang 
772bfe3f2eSlogwang 	rte_spinlock_lock(&s->sl);
782bfe3f2eSlogwang 
792bfe3f2eSlogwang 	if (unlikely(n > s->len)) {
802bfe3f2eSlogwang 		rte_spinlock_unlock(&s->sl);
812bfe3f2eSlogwang 		return -ENOENT;
822bfe3f2eSlogwang 	}
832bfe3f2eSlogwang 
842bfe3f2eSlogwang 	cache_objs = s->objs;
852bfe3f2eSlogwang 
862bfe3f2eSlogwang 	for (index = 0, len = s->len - 1; index < n;
872bfe3f2eSlogwang 			++index, len--, obj_table++)
882bfe3f2eSlogwang 		*obj_table = cache_objs[len];
892bfe3f2eSlogwang 
902bfe3f2eSlogwang 	s->len -= n;
912bfe3f2eSlogwang 	rte_spinlock_unlock(&s->sl);
922bfe3f2eSlogwang 	return 0;
932bfe3f2eSlogwang }
942bfe3f2eSlogwang 
952bfe3f2eSlogwang static unsigned
962bfe3f2eSlogwang stack_get_count(const struct rte_mempool *mp)
972bfe3f2eSlogwang {
982bfe3f2eSlogwang 	struct rte_mempool_stack *s = mp->pool_data;
992bfe3f2eSlogwang 
1002bfe3f2eSlogwang 	return s->len;
1012bfe3f2eSlogwang }
1022bfe3f2eSlogwang 
1032bfe3f2eSlogwang static void
1042bfe3f2eSlogwang stack_free(struct rte_mempool *mp)
1052bfe3f2eSlogwang {
1062bfe3f2eSlogwang 	rte_free((void *)(mp->pool_data));
1072bfe3f2eSlogwang }
1082bfe3f2eSlogwang 
1092bfe3f2eSlogwang static struct rte_mempool_ops ops_stack = {
1102bfe3f2eSlogwang 	.name = "stack",
1112bfe3f2eSlogwang 	.alloc = stack_alloc,
1122bfe3f2eSlogwang 	.free = stack_free,
1132bfe3f2eSlogwang 	.enqueue = stack_enqueue,
1142bfe3f2eSlogwang 	.dequeue = stack_dequeue,
1152bfe3f2eSlogwang 	.get_count = stack_get_count
1162bfe3f2eSlogwang };
1172bfe3f2eSlogwang 
1182bfe3f2eSlogwang MEMPOOL_REGISTER_OPS(ops_stack);
119