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 e88a36fa92c5935139e60fe67d0d371ed5485cf8
Author: dongjiuzhu1 <[email protected]>
AuthorDate: Thu Oct 5 09:27:10 2023 +0800

    libs/modlib: Adding architecture-specific memory allocator for dynamic data 
loading
    
    Arch can specific the memory allocator for data to optimize access speed.
    
    Signed-off-by: dongjiuzhu1 <[email protected]>
---
 arch/Kconfig                     | 14 ++++++++++++++
 binfmt/libelf/libelf_addrenv.c   | 10 ++++++++++
 include/nuttx/arch.h             | 20 ++++++++++++++++----
 libs/libc/modlib/modlib_load.c   |  6 ++++++
 libs/libc/modlib/modlib_unload.c |  8 ++++++--
 sched/module/mod_rmmod.c         |  4 ++++
 6 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index c545ac470f..51c39c570e 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -405,6 +405,12 @@ config ARCH_HAVE_TEXT_HEAP
        ---help---
                Special memory region for dynamic code loading
 
+config ARCH_HAVE_DATA_HEAP
+       bool
+       default n
+       ---help---
+               Special memory region for dynamic data loading
+
 config ARCH_HAVE_COPY_SECTION
        bool
        default n
@@ -626,6 +632,14 @@ config ARCH_USE_TEXT_HEAP
                regions for instruction and data and the memory region used for
                usual malloc doesn't work for instruction.
 
+config ARCH_USE_DATA_HEAP
+       bool "Enable separate data allocation for dynamic data loading"
+       default n
+       depends on ARCH_HAVE_DATA_HEAP
+       ---help---
+               This option enables architecture-specific memory allocator
+               for dynamic data loading.
+
 menuconfig ARCH_ADDRENV
        bool "Address environments"
        default n
diff --git a/binfmt/libelf/libelf_addrenv.c b/binfmt/libelf/libelf_addrenv.c
index 32c1709b30..e1d1f2abd0 100644
--- a/binfmt/libelf/libelf_addrenv.c
+++ b/binfmt/libelf/libelf_addrenv.c
@@ -159,8 +159,14 @@ errout_with_addrenv:
 
   if (loadinfo->datasize > 0)
     {
+#  if defined(CONFIG_ARCH_USE_DATA_HEAP)
+      loadinfo->dataalloc = (uintptr_t)
+                            up_dataheap_memalign(loadinfo->dataalign,
+                                                 datasize);
+#  else
       loadinfo->dataalloc = (uintptr_t)
                             kumm_memalign(loadinfo->dataalign, datasize);
+#  endif
       if (!loadinfo->dataalloc)
         {
           return -ENOMEM;
@@ -293,7 +299,11 @@ void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo)
 
   if (loadinfo->dataalloc != 0)
     {
+#  if defined(CONFIG_ARCH_USE_DATA_HEAP)
+      up_dataheap_free((FAR void *)loadinfo->dataalloc);
+#  else
       kumm_free((FAR void *)loadinfo->dataalloc);
+#  endif
     }
 #endif
 
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index 6fd6a32dd7..3aac4c6228 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -761,15 +761,27 @@ void up_textheap_free(FAR void *p);
 #endif
 
 /****************************************************************************
- * Name: up_textheap_heapmember
+ * Name: up_dataheap_memalign
  *
  * Description:
- *   Test if memory is from text heap.
+ *   Allocate memory for data sections with the specified alignment.
  *
  ****************************************************************************/
 
-#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
-bool up_textheap_heapmember(FAR void *p);
+#if defined(CONFIG_ARCH_USE_DATA_HEAP)
+FAR void *up_dataheap_memalign(size_t align, size_t size);
+#endif
+
+/****************************************************************************
+ * Name: up_dataheap_free
+ *
+ * Description:
+ *   Free memory allocated for data sections.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_ARCH_USE_DATA_HEAP)
+void up_dataheap_free(FAR void *p);
 #endif
 
 /****************************************************************************
diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c
index e77cd82e0a..9b35caab26 100644
--- a/libs/libc/modlib/modlib_load.c
+++ b/libs/libc/modlib/modlib_load.c
@@ -338,8 +338,14 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
 
       if (loadinfo->datasize > 0)
         {
+#if defined(CONFIG_ARCH_USE_DATA_HEAP)
+          loadinfo->datastart = (uintptr_t)
+                                 up_dataheap_memalign(loadinfo->dataalign,
+                                                      loadinfo->datasize);
+#else
           loadinfo->datastart = (uintptr_t)lib_memalign(loadinfo->dataalign,
                                                         loadinfo->datasize);
+#endif
           if (!loadinfo->datastart)
             {
               berr("ERROR: Failed to allocate memory for the module data\n");
diff --git a/libs/libc/modlib/modlib_unload.c b/libs/libc/modlib/modlib_unload.c
index cc8810f61e..ebd88404de 100644
--- a/libs/libc/modlib/modlib_unload.c
+++ b/libs/libc/modlib/modlib_unload.c
@@ -65,15 +65,19 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo)
       if (loadinfo->textalloc != 0)
         {
 #if defined(CONFIG_ARCH_USE_TEXT_HEAP)
-           up_textheap_free((FAR void *)loadinfo->textalloc);
+          up_textheap_free((FAR void *)loadinfo->textalloc);
 #else
-           lib_free((FAR void *)loadinfo->textalloc);
+          lib_free((FAR void *)loadinfo->textalloc);
 #endif
         }
 
       if (loadinfo->datastart != 0)
         {
+#if defined(CONFIG_ARCH_USE_DATA_HEAP)
+          up_dataheap_free((FAR void *)loadinfo->datastart);
+#else
           lib_free((FAR void *)loadinfo->datastart);
+#endif
         }
     }
   else
diff --git a/sched/module/mod_rmmod.c b/sched/module/mod_rmmod.c
index 7760e51d89..056f4a2b67 100644
--- a/sched/module/mod_rmmod.c
+++ b/sched/module/mod_rmmod.c
@@ -130,7 +130,11 @@ int rmmod(FAR void *handle)
 #else
           kmm_free((FAR void *)modp->textalloc);
 #endif
+#if defined(CONFIG_ARCH_USE_DATA_HEAP)
+          up_dataheap_free((FAR void *)modp->dataalloc);
+#else
           kmm_free((FAR void *)modp->dataalloc);
+#endif
         }
       else
         {

Reply via email to