From 4c1e9e01688864a32217e541102fa8d2df9a3d59 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 12 Jul 2017 20:04:54 -0400 Subject: [PATCH 1/3] silence compiler warnings about uninitialized variables --- port/port_posix_sse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/port/port_posix_sse.cc b/port/port_posix_sse.cc index 1e519ba0b64bef..22c1e1d336c021 100644 --- a/port/port_posix_sse.cc +++ b/port/port_posix_sse.cc @@ -50,11 +50,11 @@ static inline uint64_t LE_LOAD64(const uint8_t *p) { static inline bool HaveSSE42() { #if defined(_MSC_VER) - int cpu_info[4]; + int cpu_info[4] = {}; __cpuid(cpu_info, 1); return (cpu_info[2] & (1 << 20)) != 0; #elif defined(__GNUC__) - unsigned int eax, ebx, ecx, edx; + unsigned int eax, ebx, ecx=0, edx; __get_cpuid(1, &eax, &ebx, &ecx, &edx); return (ecx & (1 << 20)) != 0; #else From 77cfbfd250a690978a3b81d364054039467ed549 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 16 Jun 2017 19:30:24 -0400 Subject: [PATCH 2/3] crc32: move helper functions out of port_posix_sse.cc As this file is compiled with sse42 flags, it's possible that the feature discovery ends up using an unsupported runtime flag. Fix this by adding HasAcceleratedCRC32C to the port api, and requiring that it be checked before using AcceleratedCRC32C. --- port/port_example.h | 4 ++++ port/port_posix.cc | 14 ++++++++++++++ port/port_posix.h | 1 + port/port_posix_sse.cc | 19 ------------------- util/crc32c.cc | 4 ++++ 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/port/port_example.h b/port/port_example.h index 97bd669a5ed6cd..5b1d027de556eb 100644 --- a/port/port_example.h +++ b/port/port_example.h @@ -129,6 +129,10 @@ extern bool Snappy_Uncompress(const char* input_data, size_t input_length, // The concatenation of all "data[0,n-1]" fragments is the heap profile. extern bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg); +// Determine whether a working accelerated crc32 implementation exists +// Returns true if AcceleratedCRC32C is safe to call +bool HasAcceleratedCRC32C(); + // Extend the CRC to include the first n bytes of buf. // // Returns zero if the CRC cannot be extended using acceleration, else returns diff --git a/port/port_posix.cc b/port/port_posix.cc index 30e8007ae3cf11..6e55cca8bcb2a4 100644 --- a/port/port_posix.cc +++ b/port/port_posix.cc @@ -8,6 +8,10 @@ #include #include +#if defined(__GNUC__) +#include +#endif + namespace leveldb { namespace port { @@ -49,5 +53,15 @@ void InitOnce(OnceType* once, void (*initializer)()) { PthreadCall("once", pthread_once(once, initializer)); } +bool HasAcceleratedCRC32C() { +#if (__x86_64__ || __i386__) && defined(__GNUC__) + unsigned int eax, ebx, ecx, edx; + __get_cpuid(1, &eax, &ebx, &ecx, &edx); + return (ecx & (1 << 20)) != 0; +#else + return false; +#endif +} + } // namespace port } // namespace leveldb diff --git a/port/port_posix.h b/port/port_posix.h index 7e8213b22ecaf2..d85fa5d63fe0fc 100644 --- a/port/port_posix.h +++ b/port/port_posix.h @@ -152,6 +152,7 @@ inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { return false; } +bool HasAcceleratedCRC32C(); uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size); } // namespace port diff --git a/port/port_posix_sse.cc b/port/port_posix_sse.cc index 22c1e1d336c021..2d49c21dd8b0eb 100644 --- a/port/port_posix_sse.cc +++ b/port/port_posix_sse.cc @@ -19,7 +19,6 @@ #include #elif defined(__GNUC__) && defined(__SSE4_2__) #include -#include #endif #endif // defined(LEVELDB_PLATFORM_POSIX_SSE) @@ -48,20 +47,6 @@ static inline uint64_t LE_LOAD64(const uint8_t *p) { #endif // defined(_M_X64) || defined(__x86_64__) -static inline bool HaveSSE42() { -#if defined(_MSC_VER) - int cpu_info[4] = {}; - __cpuid(cpu_info, 1); - return (cpu_info[2] & (1 << 20)) != 0; -#elif defined(__GNUC__) - unsigned int eax, ebx, ecx=0, edx; - __get_cpuid(1, &eax, &ebx, &ecx, &edx); - return (ecx & (1 << 20)) != 0; -#else - return false; -#endif -} - #endif // defined(LEVELDB_PLATFORM_POSIX_SSE) // For further improvements see Intel publication at: @@ -70,10 +55,6 @@ uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { #if !defined(LEVELDB_PLATFORM_POSIX_SSE) return 0; #else - static bool have = HaveSSE42(); - if (!have) { - return 0; - } const uint8_t *p = reinterpret_cast(buf); const uint8_t *e = p + size; diff --git a/util/crc32c.cc b/util/crc32c.cc index edd61cfd6fca83..b3f40eeeed45f5 100644 --- a/util/crc32c.cc +++ b/util/crc32c.cc @@ -288,6 +288,10 @@ static inline uint32_t LE_LOAD32(const uint8_t *p) { // Determine if the CPU running this program can accelerate the CRC32C // calculation. static bool CanAccelerateCRC32C() { + if (!port::HasAcceleratedCRC32C()) + return false; + + // Double-check that the accelerated implementation functions correctly. // port::AcceleretedCRC32C returns zero when unable to accelerate. static const char kTestCRCBuffer[] = "TestCRCBuffer"; static const char kBufSize = sizeof(kTestCRCBuffer) - 1; From 8d4eb0847041a26377dc99b1c4fb5c22d4841d5e Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Fri, 16 Jun 2017 19:33:20 -0400 Subject: [PATCH 3/3] Add HasAcceleratedCRC32C to port_win.h --- port/port_win.cc | 11 +++++++++++ port/port_win.h | 1 + 2 files changed, 12 insertions(+) diff --git a/port/port_win.cc b/port/port_win.cc index 1b0f060a19caab..62e19d41038831 100644 --- a/port/port_win.cc +++ b/port/port_win.cc @@ -32,6 +32,7 @@ #include #include +#include namespace leveldb { namespace port { @@ -143,5 +144,15 @@ void AtomicPointer::NoBarrier_Store(void* v) { rep_ = v; } +bool HasAcceleratedCRC32C() { +#if (__x86_64__ || __i386__) + int cpu_info[4]; + __cpuid(cpu_info, 1); + return (cpu_info[2] & (1 << 20)) != 0; +#else + return false; +#endif +} + } } diff --git a/port/port_win.h b/port/port_win.h index 50090048228389..e8bf46ef27cd68 100644 --- a/port/port_win.h +++ b/port/port_win.h @@ -168,6 +168,7 @@ inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { return false; } +bool HasAcceleratedCRC32C(); uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size); }