[rtems commit] libdl/alloc: Add a locking interface to the allocator.

Chris Johns chrisj at rtems.org
Tue Feb 19 22:09:43 UTC 2019


Module:    rtems
Branch:    master
Commit:    22afb03411133bcf928aeb85233648a94f259b44
Changeset: http://git.rtems.org/rtems/commit/?id=22afb03411133bcf928aeb85233648a94f259b44

Author:    Chris Johns <chrisj at rtems.org>
Date:      Mon Feb 18 11:46:22 2019 +1100

libdl/alloc: Add a locking interface to the allocator.

- Allow an allocator to lock the allocations. This is needed to
  lock the heap allocator so the text and trampoline table are
  as close together as possible to allow for the largest possible
  object file size.

- Update the default heap allocator to lock the heap allocator.

- Update ELF loading to lock the allocator.

Updates #3685

---

 cpukit/include/rtems/rtl/rtl-allocator.h | 20 +++++++++++++++++++
 cpukit/libdl/rtl-alloc-heap.c            | 23 ++++++++++++++++-----
 cpukit/libdl/rtl-allocator.c             | 34 ++++++++++++++++++++++++++++++++
 cpukit/libdl/rtl-elf.c                   | 11 +++++++++++
 4 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/cpukit/include/rtems/rtl/rtl-allocator.h b/cpukit/include/rtems/rtl/rtl-allocator.h
index 1a5d615..da221fe 100644
--- a/cpukit/include/rtems/rtl/rtl-allocator.h
+++ b/cpukit/include/rtems/rtl/rtl-allocator.h
@@ -50,6 +50,8 @@ typedef enum rtems_rtl_alloc_tags rtems_rtl_alloc_tag;
 enum rtems_rtl_alloc_cmd {
   RTEMS_RTL_ALLOC_NEW,        /**< Allocate new memory. */
   RTEMS_RTL_ALLOC_DEL,        /**< Delete allocated memory. */
+  RTEMS_RTL_ALLOC_LOCK,       /**< Lock the allocator. */
+  RTEMS_RTL_ALLOC_UNLOCK,     /**< Unlock the allocator. */
   RTEMS_RTL_ALLOC_WR_ENABLE,  /**< Enable writes to the memory. */
   RTEMS_RTL_ALLOC_WR_DISABLE, /**< Disable writes to the memory. */
 };
@@ -122,6 +124,24 @@ void* rtems_rtl_alloc_new (rtems_rtl_alloc_tag tag, size_t size, bool zero);
 void rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address);
 
 /**
+ * The Runtime Loader allocator lock. An allocator that depends on a
+ * separate allocation process, for example the heap, may need to be
+ * locked during loading of an object file to make sure the locality
+ * of the memory. This call be used to lock such an allocator.
+ *  Allocator calls in this interface are protected by the RTL lock.
+ */
+void rtems_rtl_alloc_lock (void);
+
+/**
+ * The Runtime Loader allocator unlock. An allocator that depends on a
+ * separate allocation process, for example the heap, may need to be
+ * locked during loading of an object file to make sure the locality
+ * of the memory. This call can be used to unlock such an allocator.
+ * Allocator calls in this interface are protected by the RTL lock.
+ */
+void rtems_rtl_alloc_unlock (void);
+
+/**
  * The Runtime Loader allocator enable write on a bloc of allocated memory.
  *
  * @param tag The type of allocation request. Must match the address.
diff --git a/cpukit/libdl/rtl-alloc-heap.c b/cpukit/libdl/rtl-alloc-heap.c
index 4ffdaf2..f1bdcca 100644
--- a/cpukit/libdl/rtl-alloc-heap.c
+++ b/cpukit/libdl/rtl-alloc-heap.c
@@ -17,17 +17,30 @@
 
 #include "rtl-alloc-heap.h"
 
+#include <rtems/score/apimutex.h>
+
 void
 rtems_rtl_alloc_heap (rtems_rtl_alloc_cmd cmd,
                       rtems_rtl_alloc_tag tag,
                       void**              address,
                       size_t              size)
 {
-  if (cmd == RTEMS_RTL_ALLOC_NEW)
-    *address = malloc (size);
-  else if (cmd == RTEMS_RTL_ALLOC_DEL)
+  switch (cmd)
   {
-    free (*address);
-    *address = NULL;
+    case RTEMS_RTL_ALLOC_NEW:
+      *address = malloc (size);
+      break;
+    case RTEMS_RTL_ALLOC_DEL:
+      free (*address);
+      *address = NULL;
+      break;
+    case RTEMS_RTL_ALLOC_LOCK:
+      _RTEMS_Lock_allocator();
+      break;
+    case RTEMS_RTL_ALLOC_UNLOCK:
+      _RTEMS_Unlock_allocator();
+      break;
+    default:
+      break;
   }
 }
diff --git a/cpukit/libdl/rtl-allocator.c b/cpukit/libdl/rtl-allocator.c
index 01ce9e5..0dca6b2 100644
--- a/cpukit/libdl/rtl-allocator.c
+++ b/cpukit/libdl/rtl-allocator.c
@@ -108,6 +108,40 @@ rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address)
 }
 
 void
+rtems_rtl_alloc_lock (void)
+{
+  rtems_rtl_data* rtl = rtems_rtl_lock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+    printf ("rtl: alloc: lock\n");
+
+  if (rtl != NULL)
+    rtl->allocator.allocator (RTEMS_RTL_ALLOC_LOCK,
+                              RTEMS_RTL_ALLOC_OBJECT, /* should be ignored */
+                              NULL,
+                              0);
+
+  rtems_rtl_unlock ();
+}
+
+
+void
+rtems_rtl_alloc_unlock (void)
+{
+  rtems_rtl_data* rtl = rtems_rtl_lock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+    printf ("rtl: alloc: unlock\n");
+
+  if (rtl != NULL)
+    rtl->allocator.allocator (RTEMS_RTL_ALLOC_UNLOCK,
+                              RTEMS_RTL_ALLOC_OBJECT, /* should be ignored */
+                              NULL,
+                              0);
+
+  rtems_rtl_unlock ();
+}
+void
 rtems_rtl_alloc_wr_disable (rtems_rtl_alloc_tag tag, void* address)
 {
   rtems_rtl_data* rtl = rtems_rtl_lock ();
diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c
index 54ea146..963cb4b 100644
--- a/cpukit/libdl/rtl-elf.c
+++ b/cpukit/libdl/rtl-elf.c
@@ -1457,6 +1457,12 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
   obj->entry = (void*)(uintptr_t) ehdr.e_entry;
 
   /*
+   * Lock the allocator so the section memory and the trampoline memory are as
+   * clock as possible.
+   */
+  rtems_rtl_alloc_lock ();
+
+  /*
    * Allocate the sections.
    */
   if (!rtems_rtl_obj_alloc_sections (obj, fd, rtems_rtl_elf_arch_alloc, &ehdr))
@@ -1481,6 +1487,11 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
   if (!rtems_rtl_elf_alloc_trampoline (obj, relocs.unresolved))
     return false;
 
+  /*
+   * Unlock the allocator.
+   */
+  rtems_rtl_alloc_unlock ();
+
   if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols, &ehdr))
     return false;
 




More information about the vc mailing list