[Xenomai-git] Philippe Gerum : testsuite/smokey: add test suite for memory allocators
Module: xenomai-3 Branch: wip/heapmem Commit: e3019ac600cf0f3b202cf1b454b463b7cef074ff URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=e3019ac600cf0f3b202cf1b454b463b7cef074ff Author: Philippe Gerum Date: Sun Apr 22 18:20:04 2018 +0200 testsuite/smokey: add test suite for memory allocators --- configure.ac|4 + testsuite/smokey/Makefile.am| 17 +- testsuite/smokey/memcheck/Makefile.am |8 + testsuite/smokey/memcheck/memcheck.c| 884 +++ testsuite/smokey/memcheck/memcheck.h| 65 ++ testsuite/smokey/memory-heapmem/Makefile.am |9 + testsuite/smokey/memory-heapmem/heapmem.c | 51 ++ testsuite/smokey/memory-pshared/Makefile.am |9 + testsuite/smokey/memory-pshared/pshared.c | 121 testsuite/smokey/memory-tlsf/Makefile.am| 10 + testsuite/smokey/memory-tlsf/tlsf.c | 123 11 files changed, 1300 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ec2d7cb..c0ef1df 100644 --- a/configure.ac +++ b/configure.ac @@ -931,6 +931,10 @@ AC_CONFIG_FILES([ \ testsuite/smokey/timerfd/Makefile \ testsuite/smokey/tsc/Makefile \ testsuite/smokey/leaks/Makefile \ + testsuite/smokey/memcheck/Makefile \ + testsuite/smokey/memory-heapmem/Makefile \ + testsuite/smokey/memory-tlsf/Makefile \ + testsuite/smokey/memory-pshared/Makefile \ testsuite/smokey/fpu-stress/Makefile \ testsuite/smokey/net_udp/Makefile \ testsuite/smokey/net_packet_dgram/Makefile \ diff --git a/testsuite/smokey/Makefile.am b/testsuite/smokey/Makefile.am index c6fe70b..d7a71fe 100644 --- a/testsuite/smokey/Makefile.am +++ b/testsuite/smokey/Makefile.am @@ -5,6 +5,10 @@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) smokey_SOURCES = main.c +# Make sure to list modules from the most dependent to the +# least. e.g. net_common should appear after all net_* modules, +# memcheck should appear after all heapmem-* modules. + COBALT_SUBDIRS = \ arith \ bufp\ @@ -12,6 +16,9 @@ COBALT_SUBDIRS = \ fpu-stress \ iddp\ leaks \ + memory-heapmem \ + memory-tlsf \ + memcheck\ net_packet_dgram\ net_packet_raw \ net_udp \ @@ -31,11 +38,19 @@ COBALT_SUBDIRS =\ vdso-access \ xddp +if XENO_PSHARED +COBALT_SUBDIRS += memory-pshared +endif + if CONFIG_XENO_LIBS_DLOPEN COBALT_SUBDIRS += dlopen endif -MERCURY_SUBDIRS = +MERCURY_SUBDIRS = memory-heapmem memory-tlsf +if XENO_PSHARED +MERCURY_SUBDIRS += memory-pshared +endif +MERCURY_SUBDIRS += memcheck DIST_SUBDIRS = $(COBALT_SUBDIRS) $(MERCURY_SUBDIRS) diff --git a/testsuite/smokey/memcheck/Makefile.am b/testsuite/smokey/memcheck/Makefile.am new file mode 100644 index 000..482314a --- /dev/null +++ b/testsuite/smokey/memcheck/Makefile.am @@ -0,0 +1,8 @@ +noinst_LIBRARIES = libmemcheck.a +noinst_HEADERS = memcheck.h + +AM_CPPFLAGS = \ + @XENO_USER_CFLAGS@ \ + -I$(top_srcdir)/include + +libmemcheck_a_SOURCES = memcheck.c diff --git a/testsuite/smokey/memcheck/memcheck.c b/testsuite/smokey/memcheck/memcheck.c new file mode 100644 index 000..3f18477 --- /dev/null +++ b/testsuite/smokey/memcheck/memcheck.c @@ -0,0 +1,884 @@ +/* + * Copyright (C) 2018 Philippe Gerum + * + * SPDX-License-Identifier: MIT + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "memcheck.h" + +enum pattern { + alphabet_series, + digit_series, + binary_series, +}; + +struct chunk { + void *ptr; + enum pattern pattern; +}; + +struct runstats { + size_t heap_size; + size_t user_size; + size_t block_size; + int nrblocks; + long alloc_avg_ns; + long alloc_max_ns; + long free_avg_ns; + long free_max_ns; + int flags; + double overhead; + double fragmentation; + struct runstats *next; +}; + +static struct runstats *statistics; + +static int nrstats; + +static int max_results = 4; + +static inline long diff_ts(struct timespec *left, struct timespec *right) +{ + return (long long)(left->tv_sec - right->tv_sec) * ONE_BILLION + + left->tv_nsec - right->tv_nsec; +} + +static inline void swap(void *left, void *right, const size_t size) +{ + char trans[size]; + + memcpy(trans, left, size); + memcpy(left, right, size); + memcpy(right, trans, size); +} + +static void random_shuffle(void *vbase, size_t nmemb, const size_t size) +{ + struct { + char x[size]; + } __attribute__((packed)) *base = vbase; + unsigned int j, k; + double u; + + for(j = nmemb; j > 0; j--) { + u = (double)random() / RAND_MAX; + k = (unsigned int)
[Xenomai-git] Philippe Gerum : copperplate/heapobj: enable heapmem for private memory
Module: xenomai-3 Branch: wip/heapmem Commit: 26fbb2c8e0116552b8dce4c1fc2a0a1036e8c402 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=26fbb2c8e0116552b8dce4c1fc2a0a1036e8c402 Author: Philippe Gerum 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 c0ef1df..b670206 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=],[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=]) + 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 + +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 @@ -17
[Xenomai-git] Philippe Gerum : testsuite/smokey: add test suite for memory allocators
Module: xenomai-3 Branch: wip/heapmem Commit: ebfcb36320e00906fd2bf4b8058bb33620788547 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=ebfcb36320e00906fd2bf4b8058bb33620788547 Author: Philippe Gerum Date: Sun Apr 22 18:20:04 2018 +0200 testsuite/smokey: add test suite for memory allocators --- configure.ac|4 + testsuite/smokey/Makefile.am| 17 +- testsuite/smokey/memcheck/Makefile.am |8 + testsuite/smokey/memcheck/memcheck.c| 884 +++ testsuite/smokey/memcheck/memcheck.h| 65 ++ testsuite/smokey/memory-heapmem/Makefile.am |9 + testsuite/smokey/memory-heapmem/heapmem.c | 51 ++ testsuite/smokey/memory-pshared/Makefile.am |9 + testsuite/smokey/memory-pshared/pshared.c | 121 testsuite/smokey/memory-tlsf/Makefile.am| 10 + testsuite/smokey/memory-tlsf/tlsf.c | 123 11 files changed, 1300 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ec2d7cb..c0ef1df 100644 --- a/configure.ac +++ b/configure.ac @@ -931,6 +931,10 @@ AC_CONFIG_FILES([ \ testsuite/smokey/timerfd/Makefile \ testsuite/smokey/tsc/Makefile \ testsuite/smokey/leaks/Makefile \ + testsuite/smokey/memcheck/Makefile \ + testsuite/smokey/memory-heapmem/Makefile \ + testsuite/smokey/memory-tlsf/Makefile \ + testsuite/smokey/memory-pshared/Makefile \ testsuite/smokey/fpu-stress/Makefile \ testsuite/smokey/net_udp/Makefile \ testsuite/smokey/net_packet_dgram/Makefile \ diff --git a/testsuite/smokey/Makefile.am b/testsuite/smokey/Makefile.am index c6fe70b..d7a71fe 100644 --- a/testsuite/smokey/Makefile.am +++ b/testsuite/smokey/Makefile.am @@ -5,6 +5,10 @@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) smokey_SOURCES = main.c +# Make sure to list modules from the most dependent to the +# least. e.g. net_common should appear after all net_* modules, +# memcheck should appear after all heapmem-* modules. + COBALT_SUBDIRS = \ arith \ bufp\ @@ -12,6 +16,9 @@ COBALT_SUBDIRS = \ fpu-stress \ iddp\ leaks \ + memory-heapmem \ + memory-tlsf \ + memcheck\ net_packet_dgram\ net_packet_raw \ net_udp \ @@ -31,11 +38,19 @@ COBALT_SUBDIRS =\ vdso-access \ xddp +if XENO_PSHARED +COBALT_SUBDIRS += memory-pshared +endif + if CONFIG_XENO_LIBS_DLOPEN COBALT_SUBDIRS += dlopen endif -MERCURY_SUBDIRS = +MERCURY_SUBDIRS = memory-heapmem memory-tlsf +if XENO_PSHARED +MERCURY_SUBDIRS += memory-pshared +endif +MERCURY_SUBDIRS += memcheck DIST_SUBDIRS = $(COBALT_SUBDIRS) $(MERCURY_SUBDIRS) diff --git a/testsuite/smokey/memcheck/Makefile.am b/testsuite/smokey/memcheck/Makefile.am new file mode 100644 index 000..482314a --- /dev/null +++ b/testsuite/smokey/memcheck/Makefile.am @@ -0,0 +1,8 @@ +noinst_LIBRARIES = libmemcheck.a +noinst_HEADERS = memcheck.h + +AM_CPPFLAGS = \ + @XENO_USER_CFLAGS@ \ + -I$(top_srcdir)/include + +libmemcheck_a_SOURCES = memcheck.c diff --git a/testsuite/smokey/memcheck/memcheck.c b/testsuite/smokey/memcheck/memcheck.c new file mode 100644 index 000..3f18477 --- /dev/null +++ b/testsuite/smokey/memcheck/memcheck.c @@ -0,0 +1,884 @@ +/* + * Copyright (C) 2018 Philippe Gerum + * + * SPDX-License-Identifier: MIT + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "memcheck.h" + +enum pattern { + alphabet_series, + digit_series, + binary_series, +}; + +struct chunk { + void *ptr; + enum pattern pattern; +}; + +struct runstats { + size_t heap_size; + size_t user_size; + size_t block_size; + int nrblocks; + long alloc_avg_ns; + long alloc_max_ns; + long free_avg_ns; + long free_max_ns; + int flags; + double overhead; + double fragmentation; + struct runstats *next; +}; + +static struct runstats *statistics; + +static int nrstats; + +static int max_results = 4; + +static inline long diff_ts(struct timespec *left, struct timespec *right) +{ + return (long long)(left->tv_sec - right->tv_sec) * ONE_BILLION + + left->tv_nsec - right->tv_nsec; +} + +static inline void swap(void *left, void *right, const size_t size) +{ + char trans[size]; + + memcpy(trans, left, size); + memcpy(left, right, size); + memcpy(right, trans, size); +} + +static void random_shuffle(void *vbase, size_t nmemb, const size_t size) +{ + struct { + char x[size]; + } __attribute__((packed)) *base = vbase; + unsigned int j, k; + double u; + + for(j = nmemb; j > 0; j--) { + u = (double)random() / RAND_MAX; + k = (unsigned int)
[Xenomai-git] Philippe Gerum : copperplate/heapobj: enable heapmem for private memory
Module: xenomai-3 Branch: wip/heapmem Commit: df72ae08afc7711a600ad5c1b4fd5f72639f565e URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=df72ae08afc7711a600ad5c1b4fd5f72639f565e Author: Philippe Gerum 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 c0ef1df..b670206 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=],[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=]) + 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 + +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 @@ -17