From d177a0263cce4344d05188521ad53459c369b940 Mon Sep 17 00:00:00 2001 From: costan Date: Tue, 17 Apr 2018 13:23:10 -0700 Subject: Replace port_posix with port_stdcxx. The porting layer implements threading primitives: atomic pointers, condition variables, mutexes, thread-safe initialization. These are all specified in C++11, so the reference open source port implementation can become platform-independent. The porting layer will remain in place to allow the use of other implementations with more features, such as the built-in deadlock detection in abseil's Mutex. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=193245934 --- port/README | 2 +- port/port.h | 2 +- port/port_posix.cc | 53 -------------------- port/port_posix.h | 130 ------------------------------------------------- port/port_stdcxx.h | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 142 insertions(+), 185 deletions(-) delete mode 100644 port/port_posix.cc delete mode 100644 port/port_posix.h create mode 100644 port/port_stdcxx.h (limited to 'port') diff --git a/port/README b/port/README index 422563e..8b17153 100644 --- a/port/README +++ b/port/README @@ -5,6 +5,6 @@ Code in the rest of the package includes "port.h" from this directory. "port.h" in turn includes a platform specific "port_.h" file that provides the platform specific implementation. -See port_posix.h for an example of what must be provided in a platform +See port_stdcxx.h for an example of what must be provided in a platform specific header file. diff --git a/port/port.h b/port/port.h index e667db4..0975fed 100644 --- a/port/port.h +++ b/port/port.h @@ -11,7 +11,7 @@ // porting to a new platform, see "port_example.h" for documentation // of what the new port_.h file must provide. #if defined(LEVELDB_PLATFORM_POSIX) -# include "port/port_posix.h" +# include "port/port_stdcxx.h" #elif defined(LEVELDB_PLATFORM_CHROMIUM) # include "port/port_chromium.h" #endif diff --git a/port/port_posix.cc b/port/port_posix.cc deleted file mode 100644 index 04095bb..0000000 --- a/port/port_posix.cc +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2011 The LevelDB Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. See the AUTHORS file for names of contributors. - -#include "port/port_posix.h" - -#include -#include -#include - -namespace leveldb { -namespace port { - -static void PthreadCall(const char* label, int result) { - if (result != 0) { - fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); - abort(); - } -} - -Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, nullptr)); } - -Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } - -void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } - -void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } - -CondVar::CondVar(Mutex* mu) - : mu_(mu) { - PthreadCall("init cv", pthread_cond_init(&cv_, nullptr)); -} - -CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } - -void CondVar::Wait() { - PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); -} - -void CondVar::Signal() { - PthreadCall("signal", pthread_cond_signal(&cv_)); -} - -void CondVar::SignalAll() { - PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); -} - -void InitOnce(OnceType* once, void (*initializer)()) { - PthreadCall("once", pthread_once(once, initializer)); -} - -} // namespace port -} // namespace leveldb diff --git a/port/port_posix.h b/port/port_posix.h deleted file mode 100644 index 54b07b6..0000000 --- a/port/port_posix.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2011 The LevelDB Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. See the AUTHORS file for names of contributors. -// -// See port_example.h for documentation for the following types/functions. - -#ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_ -#define STORAGE_LEVELDB_PORT_PORT_POSIX_H_ - -// port/port_config.h availability is automatically detected via __has_include -// in newer compilers. If LEVELDB_HAS_PORT_CONFIG_H is defined, it overrides the -// configuration detection. -#if defined(LEVELDB_HAS_PORT_CONFIG_H) - -#if LEVELDB_HAS_PORT_CONFIG_H -#include "port/port_config.h" -#endif // LEVELDB_HAS_PORT_CONFIG_H - -#elif defined(__has_include) - -#if __has_include("port/port_config.h") -#include "port/port_config.h" -#endif // __has_include("port/port_config.h") - -#endif // defined(LEVELDB_HAS_PORT_CONFIG_H) - -#include -#if HAVE_CRC32C -#include -#endif // HAVE_CRC32C -#if HAVE_SNAPPY -#include -#endif // HAVE_SNAPPY -#include -#include -#include "port/atomic_pointer.h" -#include "port/thread_annotations.h" - -#if !HAVE_FDATASYNC -#define fdatasync fsync -#endif // !HAVE_FDATASYNC - -namespace leveldb { -namespace port { - -static const bool kLittleEndian = !LEVELDB_IS_BIG_ENDIAN; - -class CondVar; - -class LOCKABLE Mutex { - public: - Mutex(); - ~Mutex(); - - void Lock() EXCLUSIVE_LOCK_FUNCTION(); - void Unlock() UNLOCK_FUNCTION(); - void AssertHeld() ASSERT_EXCLUSIVE_LOCK() { } - - private: - friend class CondVar; - pthread_mutex_t mu_; - - // No copying - Mutex(const Mutex&); - void operator=(const Mutex&); -}; - -class CondVar { - public: - explicit CondVar(Mutex* mu); - ~CondVar(); - void Wait(); - void Signal(); - void SignalAll(); - private: - pthread_cond_t cv_; - Mutex* mu_; -}; - -typedef pthread_once_t OnceType; -#define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT -void InitOnce(OnceType* once, void (*initializer)()); - -inline bool Snappy_Compress(const char* input, size_t length, - ::std::string* output) { -#if HAVE_SNAPPY - output->resize(snappy::MaxCompressedLength(length)); - size_t outlen; - snappy::RawCompress(input, length, &(*output)[0], &outlen); - output->resize(outlen); - return true; -#endif // HAVE_SNAPPY - - return false; -} - -inline bool Snappy_GetUncompressedLength(const char* input, size_t length, - size_t* result) { -#if HAVE_SNAPPY - return snappy::GetUncompressedLength(input, length, result); -#else - return false; -#endif // HAVE_SNAPPY -} - -inline bool Snappy_Uncompress(const char* input, size_t length, - char* output) { -#if HAVE_SNAPPY - return snappy::RawUncompress(input, length, output); -#else - return false; -#endif // HAVE_SNAPPY -} - -inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { - return false; -} - -inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { -#if HAVE_CRC32C - return ::crc32c::Extend(crc, reinterpret_cast(buf), size); -#else - return 0; -#endif // HAVE_CRC32C -} - -} // namespace port -} // namespace leveldb - -#endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_ diff --git a/port/port_stdcxx.h b/port/port_stdcxx.h new file mode 100644 index 0000000..4e58cba --- /dev/null +++ b/port/port_stdcxx.h @@ -0,0 +1,140 @@ +// Copyright (c) 2018 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. + +#ifndef STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ +#define STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ + +// port/port_config.h availability is automatically detected via __has_include +// in newer compilers. If LEVELDB_HAS_PORT_CONFIG_H is defined, it overrides the +// configuration detection. +#if defined(LEVELDB_HAS_PORT_CONFIG_H) + +#if LEVELDB_HAS_PORT_CONFIG_H +#include "port/port_config.h" +#endif // LEVELDB_HAS_PORT_CONFIG_H + +#elif defined(__has_include) + +#if __has_include("port/port_config.h") +#include "port/port_config.h" +#endif // __has_include("port/port_config.h") + +#endif // defined(LEVELDB_HAS_PORT_CONFIG_H) + +#if HAVE_CRC32C +#include +#endif // HAVE_CRC32C +#if HAVE_SNAPPY +#include +#endif // HAVE_SNAPPY + +#include +#include +#include +#include // NOLINT +#include // NOLINT +#include +#include "port/atomic_pointer.h" +#include "port/thread_annotations.h" + +namespace leveldb { +namespace port { + +static const bool kLittleEndian = !LEVELDB_IS_BIG_ENDIAN; + +class CondVar; + +// Thinly wraps std::mutex. +class LOCKABLE Mutex { + public: + Mutex() = default; + ~Mutex() = default; + + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; + + void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); } + void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); } + void AssertHeld() ASSERT_EXCLUSIVE_LOCK() { } + + private: + friend class CondVar; + std::mutex mu_; +}; + +// Thinly wraps std::condition_variable. +class CondVar { + public: + explicit CondVar(Mutex* mu) : mu_(mu) { assert(mu != nullptr); } + ~CondVar() = default; + + CondVar(const CondVar&) = delete; + CondVar& operator=(const CondVar&) = delete; + + void Wait() { + std::unique_lock lock(mu_->mu_, std::adopt_lock); + cv_.wait(lock); + lock.release(); + } + void Signal() { cv_.notify_one(); } + void SignalAll() { cv_.notify_all(); } + private: + std::condition_variable cv_; + Mutex* const mu_; +}; + +using OnceType = std::once_flag; +#define LEVELDB_ONCE_INIT {} + +// Thinly wraps std::call_once. +inline void InitOnce(OnceType* once, void (*initializer)()) { + std::call_once(*once, *initializer); +} + +inline bool Snappy_Compress(const char* input, size_t length, + ::std::string* output) { +#if HAVE_SNAPPY + output->resize(snappy::MaxCompressedLength(length)); + size_t outlen; + snappy::RawCompress(input, length, &(*output)[0], &outlen); + output->resize(outlen); + return true; +#endif // HAVE_SNAPPY + + return false; +} + +inline bool Snappy_GetUncompressedLength(const char* input, size_t length, + size_t* result) { +#if HAVE_SNAPPY + return snappy::GetUncompressedLength(input, length, result); +#else + return false; +#endif // HAVE_SNAPPY +} + +inline bool Snappy_Uncompress(const char* input, size_t length, char* output) { +#if HAVE_SNAPPY + return snappy::RawUncompress(input, length, output); +#else + return false; +#endif // HAVE_SNAPPY +} + +inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { + return false; +} + +inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { +#if HAVE_CRC32C + return ::crc32c::Extend(crc, reinterpret_cast(buf), size); +#else + return 0; +#endif // HAVE_CRC32C +} + +} // namespace port +} // namespace leveldb + +#endif // STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ -- cgit v1.2.1