From 3dc62a6c23a962f8fd141df5395a53899fd4de24 Mon Sep 17 00:00:00 2001 From: YAMAMOTO Takashi Date: Fri, 2 May 2014 17:07:29 +0900 Subject: [PATCH] util: Use posix_memalign for xmalloc_cacheline if available A malloc library is expected to provide a better implementation using the knowledge of its internal details. ax_func_posix_memalign.m4 was obtained from: http://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=blob_plain;f=m4/ax_func_posix_memalign.m4 Acked-by: Ben Pfaff Signed-off-by: YAMAMOTO Takashi --- configure.ac | 1 + lib/util.c | 16 ++++++++++++ m4/ax_func_posix_memalign.m4 | 50 ++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 m4/ax_func_posix_memalign.m4 diff --git a/configure.ac b/configure.ac index 9672cb0288b..16bc6a62763 100644 --- a/configure.ac +++ b/configure.ac @@ -91,6 +91,7 @@ OVS_CHECK_ATOMIC_ALWAYS_LOCK_FREE(8) OVS_CHECK_POSIX_AIO OVS_CHECK_PTHREAD_SET_NAME OVS_CHECK_LINUX_HOST +AX_FUNC_POSIX_MEMALIGN OVS_CHECK_INCLUDE_NEXT([stdio.h string.h]) AC_CONFIG_FILES([lib/stdio.h lib/string.h]) diff --git a/lib/util.c b/lib/util.c index 1ebe22a5c7a..3dba3358dcb 100644 --- a/lib/util.c +++ b/lib/util.c @@ -189,6 +189,17 @@ BUILD_ASSERT_DECL(CACHE_LINE_SIZE >= MEM_ALIGN); void * xmalloc_cacheline(size_t size) { +#ifdef HAVE_POSIX_MEMALIGN + void *p; + int error; + + COVERAGE_INC(util_xalloc); + error = posix_memalign(&p, CACHE_LINE_SIZE, size ? size : 1); + if (error != 0) { + out_of_memory(); + } + return p; +#else void **payload; void *base; @@ -211,6 +222,7 @@ xmalloc_cacheline(size_t size) *payload = base; return (char *) payload + MEM_ALIGN; +#endif } /* Like xmalloc_cacheline() but clears the allocated memory to all zero @@ -228,9 +240,13 @@ xzalloc_cacheline(size_t size) void free_cacheline(void *p) { +#ifdef HAVE_POSIX_MEMALIGN + free(p); +#else if (p) { free(*(void **) ((uintptr_t) p - MEM_ALIGN)); } +#endif } char * diff --git a/m4/ax_func_posix_memalign.m4 b/m4/ax_func_posix_memalign.m4 new file mode 100644 index 00000000000..bd60adcbc81 --- /dev/null +++ b/m4/ax_func_posix_memalign.m4 @@ -0,0 +1,50 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_func_posix_memalign.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_FUNC_POSIX_MEMALIGN +# +# DESCRIPTION +# +# Some versions of posix_memalign (notably glibc 2.2.5) incorrectly apply +# their power-of-two check to the size argument, not the alignment +# argument. AX_FUNC_POSIX_MEMALIGN defines HAVE_POSIX_MEMALIGN if the +# power-of-two check is correctly applied to the alignment argument. +# +# LICENSE +# +# Copyright (c) 2008 Scott Pakin +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AC_DEFUN([AX_FUNC_POSIX_MEMALIGN], +[AC_CACHE_CHECK([for working posix_memalign], + [ax_cv_func_posix_memalign_works], + [AC_TRY_RUN([ +#include + +int +main () +{ + void *buffer; + + /* Some versions of glibc incorrectly perform the alignment check on + * the size word. */ + exit (posix_memalign (&buffer, sizeof(void *), 123) != 0); +} + ], + [ax_cv_func_posix_memalign_works=yes], + [ax_cv_func_posix_memalign_works=no], + [ax_cv_func_posix_memalign_works=no])]) +if test "$ax_cv_func_posix_memalign_works" = "yes" ; then + AC_DEFINE([HAVE_POSIX_MEMALIGN], [1], + [Define to 1 if `posix_memalign' works.]) +fi +])