Module: xenomai-3 Branch: wip/heapmem Commit: a36437ed07959f21cf7d63510a6bf8d53db54bbb URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=a36437ed07959f21cf7d63510a6bf8d53db54bbb
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