Revert of Try using std::call_once (patchset #1 id:1 of https://codereview.chromium...
authormtklein <mtklein@google.com>
Tue, 5 Jan 2016 02:18:50 +0000 (18:18 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 5 Jan 2016 02:18:50 +0000 (18:18 -0800)
Reason for revert:
Can't use on XP.  :(

Original issue's description:
> Try using std::call_once
>
> Now that we've got std library support, perhaps we should start using it.
> This CL acts as a little canary, and may help fix the linked bug.
>
> I'm not really sure what's going on in the linked bug, but using
> std::call_once over homegrown atomics has to be the right answer...
>
> BUG=chromium:418041
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1550893002
> CQ_EXTRA_TRYBOTS=client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot
>
> Going to land this ahead of review while the tree is quiet to see how it rolls.
> TBR=herb@google.com
>
> Committed: https://skia.googlesource.com/skia/+/8895b72f789e5dc8bb99cb9727875439005fc919

TBR=herb@google.com,mtklein@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=chromium:418041

Review URL: https://codereview.chromium.org/1552333003

src/opts/opts_check_x86.cpp

index 23f3036..3c817e1 100644 (file)
@@ -13,8 +13,8 @@
 #include "SkBlitRow.h"
 #include "SkBlitRow_opts_SSE2.h"
 #include "SkBlitRow_opts_SSE4.h"
+#include "SkOncePtr.h"
 #include "SkRTConf.h"
-#include <mutex>
 
 #if defined(_MSC_VER) && defined(_WIN64)
 #include <intrin.h>
@@ -68,12 +68,37 @@ static inline void getcpuid(int info_type, int info[4]) {
 
 ////////////////////////////////////////////////////////////////////////////////
 
+/* Fetch the SIMD level directly from the CPU, at run-time.
+ * Only checks the levels needed by the optimizations in this file.
+ */
+static int* get_SIMD_level() {
+    int cpu_info[4] = { 0, 0, 0, 0 };
+    getcpuid(1, cpu_info);
+
+    int* level = new int;
+
+    if ((cpu_info[2] & (1<<20)) != 0) {
+        *level = SK_CPU_SSE_LEVEL_SSE42;
+    } else if ((cpu_info[2] & (1<<19)) != 0) {
+        *level = SK_CPU_SSE_LEVEL_SSE41;
+    } else if ((cpu_info[2] & (1<<9)) != 0) {
+        *level = SK_CPU_SSE_LEVEL_SSSE3;
+    } else if ((cpu_info[3] & (1<<26)) != 0) {
+        *level = SK_CPU_SSE_LEVEL_SSE2;
+    } else {
+        *level = 0;
+    }
+    return level;
+}
+
+SK_DECLARE_STATIC_ONCE_PTR(int, gSIMDLevel);
+
 /* Verify that the requested SIMD level is supported in the build.
  * If not, check if the platform supports it.
  */
-static inline bool supports_simd(int level) {
+static inline bool supports_simd(int minLevel) {
 #if defined(SK_CPU_SSE_LEVEL)
-    if (level <= SK_CPU_SSE_LEVEL) {
+    if (minLevel <= SK_CPU_SSE_LEVEL) {
         return true;
     } else
 #endif
@@ -87,18 +112,7 @@ static inline bool supports_simd(int level) {
          */
         return false;
 #else
-        static std::once_flag once;
-        static int maxLevel = 0;
-        std::call_once(once, [&]{
-            int cpu_info[4] = { 0, 0, 0, 0 };
-            getcpuid(1, cpu_info);
-
-            if (cpu_info[3] & (1<<26)) { maxLevel = SK_CPU_SSE_LEVEL_SSE2 ; }
-            if (cpu_info[2] & (1<< 9)) { maxLevel = SK_CPU_SSE_LEVEL_SSSE3; }
-            if (cpu_info[2] & (1<<19)) { maxLevel = SK_CPU_SSE_LEVEL_SSE41; }
-            if (cpu_info[2] & (1<<20)) { maxLevel = SK_CPU_SSE_LEVEL_SSE42; }
-        });
-        return level <= maxLevel;
+        return minLevel <= *gSIMDLevel.get(get_SIMD_level);
 #endif
     }
 }