]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
arch: add NEON cpu feature detection
authorSage Weil <sage@inktank.com>
Tue, 3 Sep 2013 15:38:31 +0000 (08:38 -0700)
committerSage Weil <sage@inktank.com>
Wed, 4 Sep 2013 23:05:00 +0000 (16:05 -0700)
Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Dan Mick <dan.mick@inktank.com>
configure.ac
src/Makefile.am
src/arch/neon.c [new file with mode: 0644]
src/arch/neon.h [new file with mode: 0644]
src/arch/probe.cc
src/test/test_arch.c [new file with mode: 0644]

index cfe9e841e17940cebfc66a33f783ccf170252339..d042d3d282104b8b8479ef3b4fa53e216b5665e8 100644 (file)
@@ -106,6 +106,9 @@ AC_DEFUN([AC_CHECK_CC_FLAG],
 AC_CHECK_CC_FLAG([-Wtype-limits], [WARN_TYPE_LIMITS])
 AC_CHECK_CC_FLAG([-Wignored-qualifiers], [WARN_IGNORED_QUALIFIERS])
 
+# Checks for architecture stuff
+AM_CONDITIONAL([ENABLE_FPU_NEON], [case $target_cpu in arm*) true;; *) false;; esac])
+
 # Checks for libraries.
 ACX_PTHREAD
 AC_CHECK_LIB([uuid], [uuid_parse], [true], AC_MSG_FAILURE([libuuid not found]))
index 3bdec278c6fefe3dc7b510e310972cad861b68e9..7d87c7b5f602485b5249ddb3f7412ba7aaf1768f 100644 (file)
@@ -775,6 +775,10 @@ unittest_addrs_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS}
 unittest_addrs_LDADD = $(LIBGLOBAL_LDA) ${UNITTEST_LDADD}
 check_PROGRAMS += unittest_addrs
 
+unittest_arch_SOURCES = test/test_arch.c arch/intel.c arch/neon.c arch/probe.cc
+unittest_arch_CXXFLAGS = ${AM_CFLAGS}
+check_PROGRAMS += unittest_arch
+
 unittest_sharedptr_registry_SOURCES = test/common/test_sharedptr_registry.cc
 unittest_sharedptr_registry_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS}
 unittest_sharedptr_registry_LDADD = libcommon.la ${LIBGLOBAL_LDA} ${UNITTEST_LDADD}
@@ -1340,6 +1344,11 @@ AM_CXXFLAGS = \
        -Wnon-virtual-dtor \
        -Wno-invalid-offsetof
 
+if ENABLE_FPU_NEON
+AM_CFLAGS += -mfpu=neon
+AM_CXXFLAGS += -mfpu=neon
+endif
+
 if !CLANG
     AM_CXXFLAGS += -Wstrict-null-sentinel
 endif
@@ -1521,6 +1530,7 @@ libcommon_files = \
        ./ceph_ver.c \
        arch/probe.cc \
        arch/intel.c \
+       arch/neon.c \
        auth/AuthAuthorizeHandler.cc \
        auth/AuthClientHandler.cc \
        auth/AuthSessionHandler.cc \
@@ -1772,6 +1782,7 @@ noinst_HEADERS = \
        rados_sync.h \
        arch/probe.h \
        arch/intel.h \
+       arch/neon.h \
        auth/cephx/CephxAuthorizeHandler.h\
        auth/cephx/CephxKeyServer.h\
        auth/cephx/CephxProtocol.h\
diff --git a/src/arch/neon.c b/src/arch/neon.c
new file mode 100644 (file)
index 0000000..32c1f62
--- /dev/null
@@ -0,0 +1,51 @@
+#include "arch/probe.h"
+
+/* flags we export */
+int ceph_arch_neon = 0;
+
+#include <stdio.h>
+
+#if __linux__
+
+#include <elf.h>
+#include <link.h> // ElfW macro
+
+#if __arm__
+#include <asm/hwcap.h>
+#endif // __arm__
+
+static unsigned long get_auxval(unsigned long type)
+{
+       unsigned long result = 0;
+       FILE *f = fopen("/proc/self/auxv", "r");
+       if (f) {
+               ElfW(auxv_t) entry;
+               while (fread(&entry, sizeof(entry), 1, f)) {
+                       if (entry.a_type == type) {
+                               result = entry.a_un.a_val;
+                               break;
+                       }
+               }
+               fclose(f);
+       }
+       return result;
+}
+
+static unsigned long get_hwcap(void)
+{
+       return get_auxval(AT_HWCAP);
+}
+
+#endif // __linux__
+
+int ceph_arch_neon_probe(void)
+{
+#if __arm__ && __linux__
+       ceph_arch_neon = (get_hwcap() & HWCAP_NEON) == HWCAP_NEON;
+#else
+       if (0)
+               get_hwcap();  // make compiler shut up
+#endif
+       return 0;
+}
+
diff --git a/src/arch/neon.h b/src/arch/neon.h
new file mode 100644 (file)
index 0000000..0c8aacf
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef CEPH_ARCH_NEON_H
+#define CEPH_ARCH_NEON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int ceph_arch_neon;  /* true if we have ARM NEON abilities */
+
+extern int ceph_arch_neon_probe(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 9f8bc9d2d0ff7a3bc9054ce30008658fbc0a5789..8648e54d9457759fcf06c057cd1fb6b95f7bf0c8 100644 (file)
@@ -4,6 +4,7 @@
 #include "arch/probe.h"
 
 #include "arch/intel.h"
+#include "arch/neon.h"
 
 int ceph_arch_probe(void)
 {
@@ -11,6 +12,7 @@ int ceph_arch_probe(void)
     return 1;
 
   ceph_arch_intel_probe();
+  ceph_arch_neon_probe();
 
   ceph_arch_probed = 1;
   return 1;
diff --git a/src/test/test_arch.c b/src/test/test_arch.c
new file mode 100644 (file)
index 0000000..549221e
--- /dev/null
@@ -0,0 +1,19 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "arch/probe.h"
+#include "arch/intel.h"
+#include "arch/neon.h"
+
+int main(int argc, char **argv)
+{
+       ceph_arch_probe();
+       assert(ceph_arch_probed);
+
+       printf("ceph_arch_intel_sse42 = %d\n", ceph_arch_intel_sse42);
+       printf("ceph_arch_neon = %d\n", ceph_arch_neon);
+
+       return 0;
+}