arch: add NEON cpu feature detection

Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Dan Mick <dan.mick@inktank.com>
This commit is contained in:
Sage Weil 2013-09-03 08:38:31 -07:00
parent 83a4848e27
commit cfb07f1451
6 changed files with 102 additions and 0 deletions

View 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]))

View 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\

51
src/arch/neon.c Normal file
View File

@ -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;
}

16
src/arch/neon.h Normal file
View File

@ -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

View 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;

19
src/test/test_arch.c Normal file
View File

@ -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;
}