Commit fa39f253 authored by Philippe Gerum's avatar Philippe Gerum
Browse files

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.
parent fc877ef8
......@@ -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_*.
......
......@@ -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
......
......@@ -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 \
......
......@@ -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 = .
......
/*
* Copyright (C) 2018 Philippe Gerum <rpm@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;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment