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

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

commit 49d1b4198f5e9df0b2b860cc66c2a929b88ae1c8
Author: yinshengkai <yinsheng...@xiaomi.com>
AuthorDate: Wed Jan 24 23:33:02 2024 +0800

    mm: add memory pressure notification support
    
    Add mm_heap_free interface to pass remaining memory to memory pressure
    
    Signed-off-by: yinshengkai <yinsheng...@xiaomi.com>
---
 arch/sim/src/sim/sim_heap.c   | 12 ++++++++++++
 fs/procfs/fs_procfspressure.c | 22 ++++++++++++++--------
 include/nuttx/mm/mm.h         |  2 ++
 mm/mm_heap/mm_mallinfo.c      | 13 +++++++++++++
 mm/tlsf/mm_tlsf.c             | 13 +++++++++++++
 mm/umm_heap/umm_calloc.c      | 13 ++++++++++++-
 mm/umm_heap/umm_malloc.c      |  4 ++++
 mm/umm_heap/umm_memalign.c    |  4 ++++
 mm/umm_heap/umm_realloc.c     |  4 ++++
 mm/umm_heap/umm_zalloc.c      |  4 ++++
 10 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/arch/sim/src/sim/sim_heap.c b/arch/sim/src/sim/sim_heap.c
index f37eb36183..8257af7a6d 100644
--- a/arch/sim/src/sim/sim_heap.c
+++ b/arch/sim/src/sim/sim_heap.c
@@ -611,6 +611,18 @@ void up_allocate_heap(void **heap_start, size_t *heap_size)
   *heap_size  = 0;
 }
 
+/****************************************************************************
+ * Name: mm_heapfree
+ *
+ * Description:
+ *   Return the total free size (in bytes) in the heap
+ *
+ ****************************************************************************/
+
+size_t mm_heapfree(struct mm_heap_s *heap)
+{
+  return SIZE_MAX;
+}
 #else /* CONFIG_MM_CUSTOMIZE_MANAGER */
 
 void up_allocate_heap(void **heap_start, size_t *heap_size)
diff --git a/fs/procfs/fs_procfspressure.c b/fs/procfs/fs_procfspressure.c
index fa9f2c4bc5..9b2dd582cb 100644
--- a/fs/procfs/fs_procfspressure.c
+++ b/fs/procfs/fs_procfspressure.c
@@ -159,19 +159,25 @@ static ssize_t pressure_read(FAR struct file *filep, FAR 
char *buffer,
 {
   char buf[128];
   uint32_t flags;
+  size_t remain;
+  off_t offset;
   ssize_t ret;
 
-  flags = spin_lock_irqsave(&g_pressure_lock);
-  ret = procfs_snprintf(buf, sizeof(buf), "remaining %zu\n",
-                        g_remaining);
+  flags  = spin_lock_irqsave(&g_pressure_lock);
+  remain = g_remaining;
   spin_unlock_irqrestore(&g_pressure_lock, flags);
 
+  ret = procfs_snprintf(buf, sizeof(buf), "remaining %zu\n", remain);
+
   if (ret > buflen)
     {
       return -ENOMEM;
     }
 
-  memcpy(buffer, buf, ret);
+  offset = filep->f_pos;
+  ret    = procfs_memcpy(buf, ret, buffer, buflen, &offset);
+
+  filep->f_pos += ret;
   return ret;
 }
 
@@ -216,9 +222,9 @@ static ssize_t pressure_write(FAR struct file *filep, FAR 
const char *buffer,
 
   /* We should trigger the first event immediately */
 
-  priv->lasttick = CLOCK_MAX;
+  priv->lasttick  = CLOCK_MAX;
   priv->threshold = threshold;
-  priv->interval = interval;
+  priv->interval  = interval;
   spin_unlock_irqrestore(&g_pressure_lock, flags);
   return buflen;
 }
@@ -365,7 +371,7 @@ static int pressure_rewinddir(FAR struct fs_dirent_s *dir)
   FAR struct procfs_dir_priv_s *level;
 
   DEBUGASSERT(dir);
-  level = (FAR struct procfs_dir_priv_s *)dir;
+  level        = (FAR struct procfs_dir_priv_s *)dir;
   level->index = 0;
   return OK;
 }
@@ -411,7 +417,7 @@ void mm_notify_pressure(size_t remaining)
   FAR dq_entry_t *tmp;
   uint32_t flags;
 
-  flags = spin_lock_irqsave(&g_pressure_lock);
+  flags       = spin_lock_irqsave(&g_pressure_lock);
   g_remaining = remaining;
   dq_for_every_safe(&g_pressure_memory_queue, entry, tmp)
     {
diff --git a/include/nuttx/mm/mm.h b/include/nuttx/mm/mm.h
index 05149705ee..0f434afa3c 100644
--- a/include/nuttx/mm/mm.h
+++ b/include/nuttx/mm/mm.h
@@ -389,6 +389,8 @@ struct mallinfo mm_mallinfo(FAR struct mm_heap_s *heap);
 struct mallinfo_task mm_mallinfo_task(FAR struct mm_heap_s *heap,
                                       FAR const struct malltask *task);
 
+size_t mm_heapfree(FAR struct mm_heap_s *heap);
+
 /* Functions contained in kmm_mallinfo.c ************************************/
 
 #ifdef CONFIG_MM_KERNEL_HEAP
diff --git a/mm/mm_heap/mm_mallinfo.c b/mm/mm_heap/mm_mallinfo.c
index 693909202a..90d643ace8 100644
--- a/mm/mm_heap/mm_mallinfo.c
+++ b/mm/mm_heap/mm_mallinfo.c
@@ -187,3 +187,16 @@ struct mallinfo_task mm_mallinfo_task(FAR struct mm_heap_s 
*heap,
 
   return info;
 }
+
+/****************************************************************************
+ * Name: mm_heapfree
+ *
+ * Description:
+ *   Return the total free size (in bytes) in the heap
+ *
+ ****************************************************************************/
+
+size_t mm_heapfree(FAR struct mm_heap_s *heap)
+{
+  return heap->mm_heapsize - heap->mm_curused;
+}
diff --git a/mm/tlsf/mm_tlsf.c b/mm/tlsf/mm_tlsf.c
index 98f2566bf9..cbb212b688 100644
--- a/mm/tlsf/mm_tlsf.c
+++ b/mm/tlsf/mm_tlsf.c
@@ -1463,3 +1463,16 @@ void mm_free_delaylist(FAR struct mm_heap_s *heap)
        free_delaylist(heap, true);
     }
 }
+
+/****************************************************************************
+ * Name: mm_heapfree
+ *
+ * Description:
+ *   Return the total free size (in bytes) in the heap
+ *
+ ****************************************************************************/
+
+size_t mm_heapfree(FAR struct mm_heap_s *heap)
+{
+  return heap->mm_heapsize - heap->mm_curused;
+}
diff --git a/mm/umm_heap/umm_calloc.c b/mm/umm_heap/umm_calloc.c
index 66205b3d00..ee698d1f51 100644
--- a/mm/umm_heap/umm_calloc.c
+++ b/mm/umm_heap/umm_calloc.c
@@ -70,6 +70,17 @@ FAR void *calloc(size_t n, size_t elem_size)
 #else
   /* Use mm_calloc() because it implements the clear */
 
-  return mm_calloc(USR_HEAP, n, elem_size);
+  FAR void *mem = mm_calloc(USR_HEAP, n, elem_size);
+
+  if (mem == NULL)
+    {
+      set_errno(ENOMEM);
+    }
+  else
+    {
+      mm_notify_pressure(mm_heapfree(USR_HEAP));
+    }
+
+  return mem;
 #endif
 }
diff --git a/mm/umm_heap/umm_malloc.c b/mm/umm_heap/umm_malloc.c
index 9727596b40..3fa63eb59a 100644
--- a/mm/umm_heap/umm_malloc.c
+++ b/mm/umm_heap/umm_malloc.c
@@ -66,6 +66,10 @@ FAR void *malloc(size_t size)
     {
       set_errno(ENOMEM);
     }
+  else
+    {
+      mm_notify_pressure(mm_heapfree(USR_HEAP));
+    }
 
   return ret;
 #endif
diff --git a/mm/umm_heap/umm_memalign.c b/mm/umm_heap/umm_memalign.c
index c5d9236e12..9338bb6abf 100644
--- a/mm/umm_heap/umm_memalign.c
+++ b/mm/umm_heap/umm_memalign.c
@@ -93,6 +93,10 @@ FAR void *memalign(size_t alignment, size_t size)
     {
       set_errno(ENOMEM);
     }
+  else
+    {
+      mm_notify_pressure(mm_heapfree(USR_HEAP));
+    }
 
   return ret;
 #endif
diff --git a/mm/umm_heap/umm_realloc.c b/mm/umm_heap/umm_realloc.c
index 80580f8b93..d31b8de7a0 100644
--- a/mm/umm_heap/umm_realloc.c
+++ b/mm/umm_heap/umm_realloc.c
@@ -95,6 +95,10 @@ FAR void *realloc(FAR void *oldmem, size_t size)
     {
       set_errno(ENOMEM);
     }
+  else
+    {
+      mm_notify_pressure(mm_heapfree(USR_HEAP));
+    }
 
   return ret;
 #endif
diff --git a/mm/umm_heap/umm_zalloc.c b/mm/umm_heap/umm_zalloc.c
index 7aa95e853f..69ec6a2c9d 100644
--- a/mm/umm_heap/umm_zalloc.c
+++ b/mm/umm_heap/umm_zalloc.c
@@ -72,6 +72,10 @@ FAR void *zalloc(size_t size)
     {
       set_errno(ENOMEM);
     }
+  else
+    {
+      mm_notify_pressure(mm_heapfree(USR_HEAP));
+    }
 
   return ret;
 #endif

Reply via email to