diff --git a/src/leveldb/db/memtable.cc b/src/leveldb/db/memtable.cc --- a/src/leveldb/db/memtable.cc +++ b/src/leveldb/db/memtable.cc @@ -101,7 +101,7 @@ p += 8; p = EncodeVarint32(p, val_size); memcpy(p, value.data(), val_size); - assert((p + val_size) - buf == encoded_len); + assert(p + val_size == buf + encoded_len); table_.Insert(buf); } diff --git a/src/leveldb/db/version_set.cc b/src/leveldb/db/version_set.cc --- a/src/leveldb/db/version_set.cc +++ b/src/leveldb/db/version_set.cc @@ -20,7 +20,7 @@ namespace leveldb { -static int TargetFileSize(const Options* options) { +static size_t TargetFileSize(const Options* options) { return options->max_file_size; } diff --git a/src/leveldb/port/atomic_pointer.h b/src/leveldb/port/atomic_pointer.h --- a/src/leveldb/port/atomic_pointer.h +++ b/src/leveldb/port/atomic_pointer.h @@ -46,6 +46,30 @@ namespace leveldb { namespace port { +// AtomicPointer based on if available +#if defined(LEVELDB_ATOMIC_PRESENT) +class AtomicPointer { + private: + std::atomic rep_; + public: + AtomicPointer() { } + explicit AtomicPointer(void* v) : rep_(v) { } + inline void* Acquire_Load() const { + return rep_.load(std::memory_order_acquire); + } + inline void Release_Store(void* v) { + rep_.store(v, std::memory_order_release); + } + inline void* NoBarrier_Load() const { + return rep_.load(std::memory_order_relaxed); + } + inline void NoBarrier_Store(void* v) { + rep_.store(v, std::memory_order_relaxed); + } +}; + +#else + // Define MemoryBarrier() if available // Windows on x86 #if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY) @@ -142,28 +166,6 @@ } }; -// AtomicPointer based on -#elif defined(LEVELDB_ATOMIC_PRESENT) -class AtomicPointer { - private: - std::atomic rep_; - public: - AtomicPointer() { } - explicit AtomicPointer(void* v) : rep_(v) { } - inline void* Acquire_Load() const { - return rep_.load(std::memory_order_acquire); - } - inline void Release_Store(void* v) { - rep_.store(v, std::memory_order_release); - } - inline void* NoBarrier_Load() const { - return rep_.load(std::memory_order_relaxed); - } - inline void NoBarrier_Store(void* v) { - rep_.store(v, std::memory_order_relaxed); - } -}; - // Atomic pointer based on sparc memory barriers #elif defined(__sparcv9) && defined(__GNUC__) class AtomicPointer { @@ -228,6 +230,7 @@ #else #error Please implement AtomicPointer for this platform. +#endif #endif #undef LEVELDB_HAVE_MEMORY_BARRIER diff --git a/src/leveldb/port/port_example.h b/src/leveldb/port/port_example.h --- a/src/leveldb/port/port_example.h +++ b/src/leveldb/port/port_example.h @@ -129,6 +129,10 @@ // 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/src/leveldb/port/port_posix.h b/src/leveldb/port/port_posix.h --- a/src/leveldb/port/port_posix.h +++ b/src/leveldb/port/port_posix.h @@ -152,6 +152,7 @@ return false; } +bool HasAcceleratedCRC32C(); uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size); } // namespace port diff --git a/src/leveldb/port/port_posix.cc b/src/leveldb/port/port_posix.cc --- a/src/leveldb/port/port_posix.cc +++ b/src/leveldb/port/port_posix.cc @@ -8,6 +8,10 @@ #include #include +#if (defined(__x86_64__) || defined(__i386__)) && defined(__GNUC__) +#include +#endif + namespace leveldb { namespace port { @@ -49,5 +53,15 @@ PthreadCall("once", pthread_once(once, initializer)); } +bool HasAcceleratedCRC32C() { +#if (defined(__x86_64__) || defined(__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/src/leveldb/port/port_posix_sse.cc b/src/leveldb/port/port_posix_sse.cc --- a/src/leveldb/port/port_posix_sse.cc +++ b/src/leveldb/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 @@ #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, 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 @@ #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/src/leveldb/port/port_win.h b/src/leveldb/port/port_win.h --- a/src/leveldb/port/port_win.h +++ b/src/leveldb/port/port_win.h @@ -168,6 +168,7 @@ return false; } +bool HasAcceleratedCRC32C(); uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size); } diff --git a/src/leveldb/port/port_win.cc b/src/leveldb/port/port_win.cc --- a/src/leveldb/port/port_win.cc +++ b/src/leveldb/port/port_win.cc @@ -32,6 +32,7 @@ #include #include +#include namespace leveldb { namespace port { @@ -143,5 +144,15 @@ rep_ = v; } +bool HasAcceleratedCRC32C() { +#if defined(__x86_64__) || defined(__i386__) + int cpu_info[4]; + __cpuid(cpu_info, 1); + return (cpu_info[2] & (1 << 20)) != 0; +#else + return false; +#endif +} + } } diff --git a/src/leveldb/util/crc32c.cc b/src/leveldb/util/crc32c.cc --- a/src/leveldb/util/crc32c.cc +++ b/src/leveldb/util/crc32c.cc @@ -288,6 +288,10 @@ // 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; diff --git a/src/leveldb/util/logging.cc b/src/leveldb/util/logging.cc --- a/src/leveldb/util/logging.cc +++ b/src/leveldb/util/logging.cc @@ -49,7 +49,7 @@ uint64_t v = 0; int digits = 0; while (!in->empty()) { - char c = (*in)[0]; + unsigned char c = (*in)[0]; if (c >= '0' && c <= '9') { ++digits; const int delta = (c - '0');