From 54b87ae07702a06b55938d325249fd7b21b25271 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 20 Nov 2020 10:39:25 +0100 Subject: [PATCH 1/3] core: optimise ALIGN_UP() to only use 1 division No need for two divisions for an alignment macro, one is enough. Signed-off-by: Guennadi Liakhovetski --- src/include/sof/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/sof/common.h b/src/include/sof/common.h index 359f908e9f97..0fac6f049606 100644 --- a/src/include/sof/common.h +++ b/src/include/sof/common.h @@ -12,7 +12,7 @@ /* Align the number to the nearest alignment value */ #define IS_ALIGNED(size, alignment) ((size) % (alignment) == 0) #define ALIGN_UP(size, alignment) \ - ((size) + (((alignment) - ((size) % (alignment))) % (alignment))) + ((size) + (alignment) - 1 - ((size) + (alignment) - 1) % (alignment)) #define ALIGN_DOWN(size, alignment) \ ((size) - ((size) % (alignment))) #define ALIGN ALIGN_UP From f7b2b8bf3ec92115fb769819b22048a44037c793 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 20 Nov 2020 10:43:59 +0100 Subject: [PATCH 2/3] alloc: simplify align_ptr() Simplify the align_ptr() function by re-using an existing ALIGN() macro. Signed-off-by: Guennadi Liakhovetski --- src/lib/alloc.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/lib/alloc.c b/src/lib/alloc.c index af12515982c7..f99c4d04aba4 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -190,17 +190,14 @@ static void *rmalloc_sys(struct mm_heap *heap, uint32_t flags, int caps, size_t static void *align_ptr(struct mm_heap *heap, uint32_t alignment, void *ptr, struct block_hdr *hdr) { - int mod_align = 0; - /* Save unaligned ptr to block hdr */ hdr->unaligned_ptr = ptr; /* If ptr is not already aligned we calculate alignment shift */ - if (alignment && (uintptr_t)ptr % alignment) - mod_align = alignment - ((uintptr_t)ptr % alignment); + if (alignment <= 1) + return ptr; - /* Calculate aligned pointer */ - return (char *)ptr + mod_align; + return (void *)ALIGN((uintptr_t)ptr, alignment); } /* allocate single block */ From 9352b7b3d7a65cb34aa2b820f9dfcc1a41529784 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 20 Nov 2020 14:06:48 +0100 Subject: [PATCH 3/3] alloc: no need to check the same condition repeatedly alloc_heap_buffer() is trying to allocate memory from a single heap, no need to check its size on each iteration of an internal loop over maps. Signed-off-by: Guennadi Liakhovetski --- src/lib/alloc.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/lib/alloc.c b/src/lib/alloc.c index f99c4d04aba4..62db99b831ab 100644 --- a/src/lib/alloc.c +++ b/src/lib/alloc.c @@ -809,13 +809,16 @@ static void *alloc_heap_buffer(struct mm_heap *heap, uint32_t flags, platform_shared_commit(map, sizeof(*map)); } - /* size of requested buffer is adjusted for alignment purposes - * since we span more blocks we have to assume worst case scenario - */ - bytes += alignment; - /* request spans > 1 block */ if (!ptr) { + /* size of requested buffer is adjusted for alignment purposes + * since we span more blocks we have to assume worst case scenario + */ + bytes += alignment; + + if (heap->size < bytes) + return NULL; + /* * Find the best block size for request. We know, that we failed * to find a single large enough block, so, skip those. @@ -824,7 +827,7 @@ static void *alloc_heap_buffer(struct mm_heap *heap, uint32_t flags, map = &heap->map[i]; /* allocate if block size is smaller than request */ - if (heap->size >= bytes && map->block_size < bytes) { + if (map->block_size < bytes) { ptr = alloc_cont_blocks(heap, i, caps, bytes, alignment); if (ptr) { @@ -843,8 +846,6 @@ static void *alloc_heap_buffer(struct mm_heap *heap, uint32_t flags, bzero(ptr, temp_bytes); #endif - platform_shared_commit(heap, sizeof(*heap)); - return ptr; } @@ -865,6 +866,7 @@ static void *_balloc_unlocked(uint32_t flags, uint32_t caps, size_t bytes, break; ptr = alloc_heap_buffer(heap, flags, caps, bytes, alignment); + platform_shared_commit(heap, sizeof(*heap)); if (ptr) break;