Module: xenomai-3
Branch: wip/heapmem
Commit: 02de3d7eb1f1008afe67fdaeb92511e51ba5c41f
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=02de3d7eb1f1008afe67fdaeb92511e51ba5c41f

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun Apr 22 19:50:57 2018 +0200

copperplate/heapobj: enable heapmem for private memory

Make HEAPMEM the default private memory allocator for real-time
configurations (cobalt || (mercury && non-debug)).

This setting can be reverted by passing --with-localmem=tlsf.

---

 configure.ac                      |   51 ++++++++++++++++++---
 include/copperplate/heapobj.h     |   68 ++++++++++++++++++++++++++-
 lib/boilerplate/Makefile.am       |    7 ++-
 lib/copperplate/Makefile.am       |    4 ++
 lib/copperplate/heapobj-heapmem.c |   91 +++++++++++++++++++++++++++++++++++++
 5 files changed, 209 insertions(+), 12 deletions(-)

diff --git a/configure.ac b/configure.ac
index 61ebcbe..2caa4f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -327,6 +327,26 @@ if test x$use_pshared = xy; then
 fi
 AM_CONDITIONAL(XENO_PSHARED,[test x$use_pshared = xy])
 
+dnl Allocator selection
+
+localmem_allocator=heapmem
+AC_MSG_CHECKING([for process-local memory allocator])
+AC_ARG_WITH(localmem,
+    AS_HELP_STRING([--with-localmem=<heapmem | tlsf>],[Select process-local 
memory allocator]),
+    [
+       case "$withval" in
+       "" | y | ye | yes | n | no)
+           AC_MSG_ERROR([You must supply an argument to --with-localmem])
+         ;;
+       heapmem|tlsf)
+          localmem_allocator=$withval
+          ;;
+       *)
+           AC_MSG_ERROR([--localmem-allocator=<heapmem | tlsf>])
+       esac
+    ])
+AC_MSG_RESULT($localmem_allocator)
+
 dnl Registry support in user-space (FUSE-based, default: off)
 
 use_registry=
@@ -610,12 +630,31 @@ AM_CONDITIONAL(CONFIG_XENO_SHARED,[test "$enable_shared" 
= 'yes'])
 # Default sampling period (ns) used in various tests
 
AC_DEFINE_UNQUOTED(CONFIG_XENO_DEFAULT_PERIOD,$CONFIG_XENO_DEFAULT_PERIOD,[config])
 
-dnl Allocator for Copperplate
-dnl Note: in dual kernel mode, we don't want malloc, no matter what.
-dnl We switch to malloc only over the Mercury core in debug mode, to ease
-dnl debugging with valgrind, instrumented glibc etc.
-AM_CONDITIONAL(XENO_TLSF,[test $rtcore_type = cobalt -o x$debug_mode = x])
-test $rtcore_type = cobalt -o x$debug_mode = x && 
AC_DEFINE(CONFIG_XENO_TLSF,1,[config])
+dnl Allocator for Copperplate. Note: in dual kernel mode, we don't
+dnl want malloc, no matter what: pick either heapmem or tlsf, defaults
+dnl to heapmem. Force switch to malloc over the Mercury core in debug
+dnl mode, to ease debugging with valgrind, instrumented glibc etc.
+
+if test $rtcore_type = cobalt -o x$debug_mode = x; then
+   case $localmem_allocator in
+   heapmem)
+           AC_DEFINE(CONFIG_XENO_HEAPMEM,1,[config])
+           use_heapmem=y
+           use_tlsf=
+           ;;
+   tlsf)    
+           AC_DEFINE(CONFIG_XENO_TLSF,1,[config])
+           use_tlsf=y
+           use_heapmem=
+           ;;
+   esac
+else
+       use_heapmem=
+       use_tlsf=
+        AC_MSG_WARN([using malloc() for private memory in debug mode])
+fi
+AM_CONDITIONAL(XENO_TLSF,[test x$use_tlsf = xy])
+AM_CONDITIONAL(XENO_HEAPMEM,[test x$use_heapmem = xy])
 
 dnl Check for atomic builtins. For now we only check for the legacy
 dnl interface, i.e. __sync_*.
diff --git a/include/copperplate/heapobj.h b/include/copperplate/heapobj.h
index dc2a45d..c8a7773 100644
--- a/include/copperplate/heapobj.h
+++ b/include/copperplate/heapobj.h
@@ -139,7 +139,71 @@ static inline char *pvstrdup(const char *ptr)
        return strcpy(str, ptr);
 }
 
-#else /* !CONFIG_XENO_TLSF, i.e. malloc */
+#elif defined(CONFIG_XENO_HEAPMEM)
+
+#include <boilerplate/heapmem.h>
+
+extern struct heap_memory heapmem_main;
+
+static inline
+void pvheapobj_destroy(struct heapobj *hobj)
+{
+       heapmem_destroy(hobj->pool);
+}
+
+static inline
+int pvheapobj_extend(struct heapobj *hobj, size_t size, void *mem)
+{
+       return heapmem_extend(hobj->pool, mem, size);
+}
+
+static inline
+void *pvheapobj_alloc(struct heapobj *hobj, size_t size)
+{
+       return heapmem_alloc(hobj->pool, size);
+}
+
+static inline
+void pvheapobj_free(struct heapobj *hobj, void *ptr)
+{
+       heapmem_free(hobj->pool, ptr);
+}
+
+static inline
+size_t pvheapobj_validate(struct heapobj *hobj, void *ptr)
+{
+       ssize_t size = heapmem_check(hobj->pool, ptr);
+       return size < 0 ? 0 : size;
+}
+
+static inline
+size_t pvheapobj_inquire(struct heapobj *hobj)
+{
+       return heapmem_used_size(hobj->pool);
+}
+
+static inline void *pvmalloc(size_t size)
+{
+       return heapmem_alloc(&heapmem_main, size);
+}
+
+static inline void pvfree(void *ptr)
+{
+       heapmem_free(&heapmem_main, ptr);
+}
+
+static inline char *pvstrdup(const char *ptr)
+{
+       char *str;
+
+       str = (char *)pvmalloc(strlen(ptr) + 1);
+       if (str == NULL)
+               return NULL;
+
+       return strcpy(str, ptr);
+}
+
+#else /* !CONFIG_XENO_HEAPMEM, i.e. malloc */
 
 #include <malloc.h>
 
@@ -176,7 +240,7 @@ size_t pvheapobj_inquire(struct heapobj *hobj);
 
 size_t pvheapobj_validate(struct heapobj *hobj, void *ptr);
 
-#endif /* !CONFIG_XENO_TLSF */
+#endif /* !CONFIG_XENO_HEAPMEM */
 
 #ifdef CONFIG_XENO_PSHARED
 
diff --git a/lib/boilerplate/Makefile.am b/lib/boilerplate/Makefile.am
index 9362ec4..7181290 100644
--- a/lib/boilerplate/Makefile.am
+++ b/lib/boilerplate/Makefile.am
@@ -71,12 +71,11 @@ libiniparser_la_CPPFLAGS    =               \
 
 EXTRA_DIST = iniparser/README iniparser/LICENSE
 
-# We always build the tlsf/malloc support. In the pshared case, it
-# will provide for private memory allocation.
-if XENO_TLSF
+# Always build TLSF for benchmarking purpose via the
+# smokey testsuite.
+
 libboilerplate_la_LIBADD +=    libtlsf.la
 noinst_LTLIBRARIES += libtlsf.la
-endif
 
 libtlsf_la_SOURCES =   \
        tlsf/tlsf.c     \
diff --git a/lib/copperplate/Makefile.am b/lib/copperplate/Makefile.am
index 2ad5e1e..f832d1c 100644
--- a/lib/copperplate/Makefile.am
+++ b/lib/copperplate/Makefile.am
@@ -43,8 +43,12 @@ endif
 if XENO_TLSF
 libcopperplate_la_SOURCES += heapobj-tlsf.c
 else
+if XENO_HEAPMEM
+libcopperplate_la_SOURCES += heapobj-heapmem.c
+else
 libcopperplate_la_SOURCES += heapobj-malloc.c
 endif
+endif
 
 SUBDIRS = .
 
diff --git a/lib/copperplate/heapobj-heapmem.c 
b/lib/copperplate/heapobj-heapmem.c
new file mode 100644
index 0000000..5c0ce9b
--- /dev/null
+++ b/lib/copperplate/heapobj-heapmem.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 Philippe Gerum <r...@xenomai.org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
+ */
+#include <stdlib.h>
+#include "boilerplate/heapmem.h"
+#include "copperplate/heapobj.h"
+#include "copperplate/debug.h"
+#include "copperplate/tunables.h"
+#include "xenomai/init.h"
+
+#define MIN_HEAPMEM_HEAPSZ  (64 * 1024)
+
+struct heap_memory heapmem_main;
+
+int __heapobj_init_private(struct heapobj *hobj, const char *name,
+                          size_t size, void *mem)
+{
+       void *_mem = mem;
+       int ret;
+
+       if (mem == NULL) {
+               _mem = __STD(malloc(size));
+               if (_mem == NULL)
+                       return -ENOMEM;
+       }
+       
+       if (name)
+               snprintf(hobj->name, sizeof(hobj->name), "%s", name);
+       else
+               snprintf(hobj->name, sizeof(hobj->name), "%p", hobj);
+
+       ret = heapmem_init(hobj->pool, _mem, size);
+       if (ret) {
+               if (mem == NULL)
+                       __STD(free(_mem));
+               return ret;
+       }
+
+       hobj->pool = _mem;
+       hobj->size = size;
+
+       return 0;
+}
+
+int heapobj_init_array_private(struct heapobj *hobj, const char *name,
+                              size_t size, int elems)
+{
+       return __bt(__heapobj_init_private(hobj, name,
+                          HEAPMEM_ARENA_SIZE(size * elems), NULL));
+}
+
+int heapobj_pkg_init_private(void)
+{
+       size_t size;
+       void *mem;
+       int ret;
+
+#ifdef CONFIG_XENO_PSHARED
+       size = MIN_HEAPMEM_HEAPSZ;
+#else
+       size = __copperplate_setup_data.mem_pool;
+       if (size < MIN_HEAPMEM_HEAPSZ)
+               size = MIN_HEAPMEM_HEAPSZ;
+#endif
+       size = HEAPMEM_ARENA_SIZE(size);
+       mem = __STD(malloc(size));
+       if (mem == NULL)
+               return -ENOMEM;
+
+       ret = heapmem_init(&heapmem_main, mem, size);
+       if (ret) {
+               __STD(free(mem));
+               return ret;
+       }
+
+       return 0;
+}


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
https://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to