From e735f163035c4df79024d3bfee8adbe4e4409e1e Mon Sep 17 00:00:00 2001 From: mtklein Date: Mon, 4 Jan 2016 18:18:50 -0800 Subject: [PATCH] Revert of Try using std::call_once (patchset #1 id:1 of https://codereview.chromium.org/1550893002/ ) 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 | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/opts/opts_check_x86.cpp b/src/opts/opts_check_x86.cpp index 23f3036..3c817e1 100644 --- a/src/opts/opts_check_x86.cpp +++ b/src/opts/opts_check_x86.cpp @@ -13,8 +13,8 @@ #include "SkBlitRow.h" #include "SkBlitRow_opts_SSE2.h" #include "SkBlitRow_opts_SSE4.h" +#include "SkOncePtr.h" #include "SkRTConf.h" -#include #if defined(_MSC_VER) && defined(_WIN64) #include @@ -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 } } -- 2.7.4