diff options
author | costan <costan@google.com> | 2018-04-17 13:23:10 -0700 |
---|---|---|
committer | Victor Costan <pwnall@chromium.org> | 2018-04-17 13:26:47 -0700 |
commit | d177a0263cce4344d05188521ad53459c369b940 (patch) | |
tree | 0777844f4688d9f27040a9fe5defdb8b98c402c9 /port | |
parent | 14cce848e7b8a040a8f457d5a796722a55e19597 (diff) | |
download | leveldb-d177a0263cce4344d05188521ad53459c369b940.tar.gz |
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
Diffstat (limited to 'port')
-rw-r--r-- | port/README | 2 | ||||
-rw-r--r-- | port/port.h | 2 | ||||
-rw-r--r-- | port/port_posix.cc | 53 | ||||
-rw-r--r-- | port/port_stdcxx.h (renamed from port/port_posix.h) | 74 |
4 files changed, 44 insertions, 87 deletions
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_<platform>.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_<platform>.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 <cstdlib> -#include <stdio.h> -#include <string.h> - -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_stdcxx.h index 54b07b6..4e58cba 100644 --- a/port/port_posix.h +++ b/port/port_stdcxx.h @@ -1,11 +1,9 @@ -// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// 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. -// -// 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_ +#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 @@ -24,22 +22,22 @@ #endif // defined(LEVELDB_HAS_PORT_CONFIG_H) -#include <pthread.h> #if HAVE_CRC32C #include <crc32c/crc32c.h> #endif // HAVE_CRC32C #if HAVE_SNAPPY #include <snappy.h> #endif // HAVE_SNAPPY + +#include <stddef.h> #include <stdint.h> +#include <cassert> +#include <condition_variable> // NOLINT +#include <mutex> // NOLINT #include <string> #include "port/atomic_pointer.h" #include "port/thread_annotations.h" -#if !HAVE_FDATASYNC -#define fdatasync fsync -#endif // !HAVE_FDATASYNC - namespace leveldb { namespace port { @@ -47,39 +45,52 @@ static const bool kLittleEndian = !LEVELDB_IS_BIG_ENDIAN; class CondVar; +// Thinly wraps std::mutex. class LOCKABLE Mutex { public: - Mutex(); - ~Mutex(); + Mutex() = default; + ~Mutex() = default; + + Mutex(const Mutex&) = delete; + Mutex& operator=(const Mutex&) = delete; - void Lock() EXCLUSIVE_LOCK_FUNCTION(); - void Unlock() UNLOCK_FUNCTION(); + void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); } + void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); } void AssertHeld() ASSERT_EXCLUSIVE_LOCK() { } private: friend class CondVar; - pthread_mutex_t mu_; - - // No copying - Mutex(const Mutex&); - void operator=(const Mutex&); + std::mutex mu_; }; +// Thinly wraps std::condition_variable. class CondVar { public: - explicit CondVar(Mutex* mu); - ~CondVar(); - void Wait(); - void Signal(); - void SignalAll(); + 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<std::mutex> lock(mu_->mu_, std::adopt_lock); + cv_.wait(lock); + lock.release(); + } + void Signal() { cv_.notify_one(); } + void SignalAll() { cv_.notify_all(); } private: - pthread_cond_t cv_; - Mutex* mu_; + std::condition_variable cv_; + Mutex* const mu_; }; -typedef pthread_once_t OnceType; -#define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT -void InitOnce(OnceType* once, void (*initializer)()); +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) { @@ -103,8 +114,7 @@ inline bool Snappy_GetUncompressedLength(const char* input, size_t length, #endif // HAVE_SNAPPY } -inline bool Snappy_Uncompress(const char* input, size_t length, - char* output) { +inline bool Snappy_Uncompress(const char* input, size_t length, char* output) { #if HAVE_SNAPPY return snappy::RawUncompress(input, length, output); #else @@ -127,4 +137,4 @@ inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { } // namespace port } // namespace leveldb -#endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_ +#endif // STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ |