[dpdk-dev] [PATCH 03/41] eal: make malloc heap a doubly-linked list
Olivier Matz
olivier.matz at 6wind.com
Mon Mar 19 18:33:41 CET 2018
On Sat, Mar 03, 2018 at 01:45:51PM +0000, Anatoly Burakov wrote:
> As we are preparing for dynamic memory allocation, we need to be
> able to handle holes in our malloc heap, hence we're switching to
> doubly linked list, and prepare infrastructure to support it.
>
> Since our heap is now aware where are our first and last elements,
> there is no longer any need to have a dummy element at the end of
> each heap, so get rid of that as well. Instead, let insert/remove/
> join/split operations handle end-of-list conditions automatically.
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov at intel.com>
> ---
> lib/librte_eal/common/include/rte_malloc_heap.h | 6 +
> lib/librte_eal/common/malloc_elem.c | 200 +++++++++++++++++++-----
> lib/librte_eal/common/malloc_elem.h | 14 +-
> lib/librte_eal/common/malloc_heap.c | 8 +-
> 4 files changed, 179 insertions(+), 49 deletions(-)
>
> diff --git a/lib/librte_eal/common/include/rte_malloc_heap.h b/lib/librte_eal/common/include/rte_malloc_heap.h
> index ba99ed9..9ec4b62 100644
> --- a/lib/librte_eal/common/include/rte_malloc_heap.h
> +++ b/lib/librte_eal/common/include/rte_malloc_heap.h
> @@ -13,12 +13,18 @@
> /* Number of free lists per heap, grouped by size. */
> #define RTE_HEAP_NUM_FREELISTS 13
>
> +/* dummy definition, for pointers */
> +struct malloc_elem;
> +
> /**
> * Structure to hold malloc heap
> */
> struct malloc_heap {
> rte_spinlock_t lock;
> LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
> + struct malloc_elem *first;
> + struct malloc_elem *last;
> +
> unsigned alloc_count;
> size_t total_size;
> } __rte_cache_aligned;
> diff --git a/lib/librte_eal/common/malloc_elem.c b/lib/librte_eal/common/malloc_elem.c
> index ea041e2..eb41200 100644
> --- a/lib/librte_eal/common/malloc_elem.c
> +++ b/lib/librte_eal/common/malloc_elem.c
> @@ -31,6 +31,7 @@ malloc_elem_init(struct malloc_elem *elem,
> elem->heap = heap;
> elem->ms = ms;
> elem->prev = NULL;
> + elem->next = NULL;
> memset(&elem->free_list, 0, sizeof(elem->free_list));
> elem->state = ELEM_FREE;
> elem->size = size;
> @@ -39,15 +40,56 @@ malloc_elem_init(struct malloc_elem *elem,
> set_trailer(elem);
> }
>
> -/*
> - * Initialize a dummy malloc_elem header for the end-of-memseg marker
> - */
> void
> -malloc_elem_mkend(struct malloc_elem *elem, struct malloc_elem *prev)
> +malloc_elem_insert(struct malloc_elem *elem)
> {
> - malloc_elem_init(elem, prev->heap, prev->ms, 0);
> - elem->prev = prev;
> - elem->state = ELEM_BUSY; /* mark busy so its never merged */
> + struct malloc_elem *prev_elem, *next_elem;
> + struct malloc_heap *heap = elem->heap;
> +
> + if (heap->first == NULL && heap->last == NULL) {
> + /* if empty heap */
> + heap->first = elem;
> + heap->last = elem;
> + prev_elem = NULL;
> + next_elem = NULL;
> + } else if (elem < heap->first) {
> + /* if lower than start */
> + prev_elem = NULL;
> + next_elem = heap->first;
> + heap->first = elem;
> + } else if (elem > heap->last) {
> + /* if higher than end */
> + prev_elem = heap->last;
> + next_elem = NULL;
> + heap->last = elem;
> + } else {
> + /* the new memory is somewhere inbetween start and end */
> + uint64_t dist_from_start, dist_from_end;
> +
> + dist_from_end = RTE_PTR_DIFF(heap->last, elem);
> + dist_from_start = RTE_PTR_DIFF(elem, heap->first);
> +
> + /* check which is closer, and find closest list entries */
> + if (dist_from_start < dist_from_end) {
> + prev_elem = heap->first;
> + while (prev_elem->next < elem)
> + prev_elem = prev_elem->next;
> + next_elem = prev_elem->next;
> + } else {
> + next_elem = heap->last;
> + while (next_elem->prev > elem)
> + next_elem = next_elem->prev;
> + prev_elem = next_elem->prev;
> + }
> + }
> +
> + /* insert new element */
> + elem->prev = prev_elem;
> + elem->next = next_elem;
> + if (prev_elem)
> + prev_elem->next = elem;
> + if (next_elem)
> + next_elem->prev = elem;
> }
Would it be possible here to use a TAILQ? If yes, it could be
easier to read.
More information about the dev
mailing list