summaryrefslogtreecommitdiff
path: root/port
diff options
context:
space:
mode:
authorcostan <costan@google.com>2018-04-17 13:23:10 -0700
committerVictor Costan <pwnall@chromium.org>2018-04-17 13:26:47 -0700
commitd177a0263cce4344d05188521ad53459c369b940 (patch)
tree0777844f4688d9f27040a9fe5defdb8b98c402c9 /port
parent14cce848e7b8a040a8f457d5a796722a55e19597 (diff)
downloadleveldb-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/README2
-rw-r--r--port/port.h2
-rw-r--r--port/port_posix.cc53
-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_