Switch includes of PThread to the portability header
[folly.git] / folly / CpuId.h
index fe3d58bb970fac74a1f218fcf11c3142a745cc6e..5e06513ccad44326d506c2e114d621fa70e79d84 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <cstdint>
 #include <folly/Portability.h>
 
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
 namespace folly {
 
 /**
@@ -28,20 +32,26 @@ namespace folly {
  */
 class CpuId {
  public:
-  CpuId() {
+  // Always inline in order for this to be usable from a __ifunc__.
+  // In shared library mde, a __ifunc__ runs at relocation time, while the
+  // PLT hasn't been fully populated yet; thus, ifuncs cannot use symbols
+  // with potentially external linkage. (This issue is less likely in opt
+  // mode since inlining happens more likely, and it doesn't happen for
+  // statically linked binaries which don't depend on the PLT)
+  FOLLY_ALWAYS_INLINE CpuId() {
 #ifdef _MSC_VER
     int reg[4];
     __cpuid(static_cast<int*>(reg), 0);
     const int n = reg[0];
     if (n >= 1) {
       __cpuid(static_cast<int*>(reg), 1);
-      f1c_ = reg[2];
-      f1d_ = reg[3];
+      f1c_ = uint32_t(reg[2]);
+      f1d_ = uint32_t(reg[3]);
     }
     if (n >= 7) {
       __cpuidex(static_cast<int*>(reg), 7, 0);
-      f7b_ = reg[1];
-      f7c_ = reg[2];
+      f7b_ = uint32_t(reg[1]);
+      f7c_ = uint32_t(reg[2]);
     }
 #elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && \
     defined(__GNUC__)
@@ -87,9 +97,12 @@ class CpuId {
 #endif
   }
 
-#define X(name, r, bit) bool name() const { return (r) & (1U << bit); }
+#define X(name, r, bit)                   \
+  FOLLY_ALWAYS_INLINE bool name() const { \
+    return ((r) & (1U << bit)) != 0;      \
+  }
 
-  // cpuid(1): Processor Info and Feature Bits.
+// cpuid(1): Processor Info and Feature Bits.
 #define C(name, bit) X(name, f1c_, bit)
   C(sse3, 0)
   C(pclmuldq, 1)