This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 36e56e9d37ac24d160b50a6f564c88d8df75c8da
Author: Marco Casaroli <[email protected]>
AuthorDate: Thu Oct 29 18:56:46 2026 +0100

    mm/mm_gran: Start the search at the lowest free granule.
    
    The search still read each word of the table below the first free
    granule.  With 20000 used granules, a search for one granule read 625
    words.
    
    Keep the position of the lowest free granule in struct gran_s
    (lowfree).  gran_set() moves it up when an allocation takes that
    granule, and gran_clear() moves it down when a lower granule becomes
    free.  gran_search() starts at lowfree.  The result does not change,
    because no granule below lowfree is free.
    
    In a host test with 20000 used granules, one search for one granule
    takes 2 ns, not 178 ns.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 mm/mm_gran/mm_gran.h      |  1 +
 mm/mm_gran/mm_grantable.c | 17 ++++++++++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/mm/mm_gran/mm_gran.h b/mm/mm_gran/mm_gran.h
index c56e1f517ff..7738b08fd74 100644
--- a/mm/mm_gran/mm_gran.h
+++ b/mm/mm_gran/mm_gran.h
@@ -70,6 +70,7 @@ struct gran_s
   uint8_t    log2gran;  /* Log base 2 of the size of one granule */
   uint8_t    log2align; /* Log base 2 of required alignment */
   uint32_t   ngranules; /* The total number of (aligned) granules in the heap 
*/
+  uint32_t   lowfree;   /* No granule below this one is free */
 #ifdef CONFIG_GRAN_INTR
   irqstate_t irqstate;  /* For exclusive access to the GAT */
   spinlock_t lock;
diff --git a/mm/mm_gran/mm_grantable.c b/mm/mm_gran/mm_grantable.c
index 1ebb0047d43..9194edcd6f8 100644
--- a/mm/mm_gran/mm_grantable.c
+++ b/mm/mm_gran/mm_grantable.c
@@ -296,7 +296,7 @@ failure:
 
 int gran_search(const gran_t *gran, size_t size)
 {
-  size_t posi = 0;
+  size_t posi;
   size_t used;
 
   if (gran == NULL || gran->ngranules < size)
@@ -304,6 +304,9 @@ int gran_search(const gran_t *gran, size_t size)
       return -EINVAL;
     }
 
+  /* No granule below lowfree is free: start there */
+
+  posi = gran->lowfree;
   for (; ; )
     {
       /* The first free granule, then the first used one after it */
@@ -334,6 +337,13 @@ int gran_set(gran_t *gran, size_t posi, size_t size)
   if (ret == OK)
     {
       gran_set_(gran, &rang, true);
+
+      /* The range took the lowest free granule: the next one is above it */
+
+      if (gran->lowfree >= posi && gran->lowfree < posi + size)
+        {
+          gran->lowfree = posi + size;
+        }
     }
 
   return ret;
@@ -349,6 +359,11 @@ int gran_clear(gran_t *gran, size_t posi, size_t size)
   if (ret == OK)
     {
       gran_set_(gran, &rang, false);
+
+      if (posi < gran->lowfree)
+        {
+          gran->lowfree = posi;
+        }
     }
 
   return ret;

Reply via email to