summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-08-20 21:51:16 -0700
committerSage Weil <sage@inktank.com>2013-08-22 09:14:59 -0700
commitf008ac427c9e4a70473f87ac789e75bcf045d878 (patch)
tree87577377e1f8670a998b7059117dd8407b0fa4e7
parent841a695527da8da98eda15b3d6bd17c1de4eacf7 (diff)
downloadceph-f008ac427c9e4a70473f87ac789e75bcf045d878.tar.gz
arch: add cpu probing
For now, just a check to see if we have SSE4.2. Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/Makefile.am4
-rw-r--r--src/arch/intel.c46
-rw-r--r--src/arch/intel.h16
-rw-r--r--src/arch/probe.cc20
-rw-r--r--src/arch/probe.h16
5 files changed, 102 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 34e86fa1bf9..22776b5bb2a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1504,6 +1504,8 @@ crush_files = \
# this list ommits the ceph_ver.c file
libcommon_files = \
./ceph_ver.c \
+ arch/probe.cc \
+ arch/intel.c \
auth/AuthAuthorizeHandler.cc \
auth/AuthClientHandler.cc \
auth/AuthSessionHandler.cc \
@@ -1746,6 +1748,8 @@ python_PYTHON = pybind/rados.py \
# that autotools doesn't magically identify.
noinst_HEADERS = \
rados_sync.h \
+ arch/probe.h \
+ arch/intel.h \
auth/cephx/CephxAuthorizeHandler.h\
auth/cephx/CephxKeyServer.h\
auth/cephx/CephxProtocol.h\
diff --git a/src/arch/intel.c b/src/arch/intel.c
new file mode 100644
index 00000000000..0513da53c23
--- /dev/null
+++ b/src/arch/intel.c
@@ -0,0 +1,46 @@
+#include "arch/probe.h"
+
+/* flags we export */
+int ceph_arch_intel_sse42 = 0;
+
+
+/* this probably isn't specific enough for x86_64? fix me someday */
+#ifdef __LP64__
+
+/* intel cpu? */
+static void do_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
+ unsigned int *edx)
+{
+ int id = *eax;
+
+ asm("movl %4, %%eax;"
+ "cpuid;"
+ "movl %%eax, %0;"
+ "movl %%ebx, %1;"
+ "movl %%ecx, %2;"
+ "movl %%edx, %3;"
+ : "=r" (*eax), "=r" (*ebx), "=r" (*ecx), "=r" (*edx)
+ : "r" (id)
+ : "eax", "ebx", "ecx", "edx");
+}
+
+int ceph_arch_intel_probe(void)
+{
+ /* i know how to check this on x86_64... */
+ unsigned int eax = 1, ebx, ecx, edx;
+ do_cpuid(&eax, &ebx, &ecx, &edx);
+ if ((ecx & (1 << 20)) != 0) {
+ ceph_arch_intel_sse42 = 1;
+ }
+ return 0;
+}
+
+#else // __LP64__
+
+int ceph_arch_intel_probe(void)
+{
+ /* no features */
+ return 0;
+}
+
+#endif // __LP64__
diff --git a/src/arch/intel.h b/src/arch/intel.h
new file mode 100644
index 00000000000..aefb64eaa7f
--- /dev/null
+++ b/src/arch/intel.h
@@ -0,0 +1,16 @@
+#ifndef CEPH_ARCH_INTEL_H
+#define CEPH_ARCH_INTEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int ceph_arch_intel_sse42; /* true if we have sse 4.2 features */
+
+extern int ceph_arch_intel_probe(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/arch/probe.cc b/src/arch/probe.cc
new file mode 100644
index 00000000000..9f8bc9d2d0f
--- /dev/null
+++ b/src/arch/probe.cc
@@ -0,0 +1,20 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "arch/probe.h"
+
+#include "arch/intel.h"
+
+int ceph_arch_probe(void)
+{
+ if (ceph_arch_probed)
+ return 1;
+
+ ceph_arch_intel_probe();
+
+ ceph_arch_probed = 1;
+ return 1;
+}
+
+// do this once using the magic of c++.
+int ceph_arch_probed = ceph_arch_probe();
diff --git a/src/arch/probe.h b/src/arch/probe.h
new file mode 100644
index 00000000000..a789c4e864c
--- /dev/null
+++ b/src/arch/probe.h
@@ -0,0 +1,16 @@
+#ifndef CEPH_ARCH_PROBE_H
+#define CEPH_ARCH_PROBE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int ceph_arch_probed; /* non-zero if we've probed features */
+
+extern int ceph_arch_probe(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif