Skip to content

Commit

Permalink
Replace port_posix with port_stdcxx.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
pwnall committed Apr 17, 2018
1 parent 14cce84 commit d177a02
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 135 deletions.
64 changes: 16 additions & 48 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,33 +79,10 @@ if(BUILD_SHARED_LIBS)
add_compile_options(-fvisibility=hidden)
endif(BUILD_SHARED_LIBS)

# POSIX code is specified separately so we can leave it out in the future.
add_library(leveldb_port_posix OBJECT "")
target_sources(leveldb_port_posix
PRIVATE
"${PROJECT_SOURCE_DIR}/port/port_posix.cc"

PUBLIC
# The headers below are dependencies for leveldb, but aren't needed by users
# that link to the installed version of leveldb and rely on its public API.
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/port/atomic_pointer.h>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/port/port_posix.h>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/port/port.h>
)
if (NOT HAVE_CXX17_HAS_INCLUDE)
target_compile_definitions(leveldb_port_posix
PRIVATE
LEVELDB_HAS_PORT_CONFIG_H=1
)
endif(NOT HAVE_CXX17_HAS_INCLUDE)
if(BUILD_SHARED_LIBS)
set_property(TARGET leveldb_port_posix PROPERTY POSITION_INDEPENDENT_CODE ON)
endif(BUILD_SHARED_LIBS)

add_library(leveldb "")
target_sources(leveldb
PRIVATE
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
"${PROJECT_SOURCE_DIR}/db/builder.cc"
"${PROJECT_SOURCE_DIR}/db/builder.h"
"${PROJECT_SOURCE_DIR}/db/c.cc"
Expand Down Expand Up @@ -136,6 +113,8 @@ target_sources(leveldb
"${PROJECT_SOURCE_DIR}/db/version_set.h"
"${PROJECT_SOURCE_DIR}/db/write_batch_internal.h"
"${PROJECT_SOURCE_DIR}/db/write_batch.cc"
"${PROJECT_SOURCE_DIR}/port/atomic_pointer.h"
"${PROJECT_SOURCE_DIR}/port/port_stdcxx.h"
"${PROJECT_SOURCE_DIR}/port/port.h"
"${PROJECT_SOURCE_DIR}/port/thread_annotations.h"
"${PROJECT_SOURCE_DIR}/table/block_builder.cc"
Expand Down Expand Up @@ -163,7 +142,6 @@ target_sources(leveldb
"${PROJECT_SOURCE_DIR}/util/comparator.cc"
"${PROJECT_SOURCE_DIR}/util/crc32c.cc"
"${PROJECT_SOURCE_DIR}/util/crc32c.h"
"${PROJECT_SOURCE_DIR}/util/env_posix.cc"
"${PROJECT_SOURCE_DIR}/util/env.cc"
"${PROJECT_SOURCE_DIR}/util/filter_policy.cc"
"${PROJECT_SOURCE_DIR}/util/hash.cc"
Expand All @@ -172,10 +150,8 @@ target_sources(leveldb
"${PROJECT_SOURCE_DIR}/util/logging.h"
"${PROJECT_SOURCE_DIR}/util/mutexlock.h"
"${PROJECT_SOURCE_DIR}/util/options.cc"
"${PROJECT_SOURCE_DIR}/util/posix_logger.h"
"${PROJECT_SOURCE_DIR}/util/random.h"
"${PROJECT_SOURCE_DIR}/util/status.cc"
$<TARGET_OBJECTS:leveldb_port_posix>

# Only CMake 3.3+ supports PUBLIC sources in targets exported by "install".
$<$<VERSION_GREATER:CMAKE_VERSION,3.2>:PUBLIC>
Expand All @@ -195,12 +171,21 @@ target_sources(leveldb
"${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h"
"${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h"
)

# POSIX code is specified separately so we can leave it out in the future.
target_sources(leveldb
PRIVATE
"${PROJECT_SOURCE_DIR}/util/env_posix.cc"
"${PROJECT_SOURCE_DIR}/util/posix_logger.h"
)

# MemEnv is not part of the interface and could be pulled to a separate library.
target_sources(leveldb
PRIVATE
"${PROJECT_SOURCE_DIR}/helpers/memenv/memenv.cc"
"${PROJECT_SOURCE_DIR}/helpers/memenv/memenv.h"
)

target_include_directories(leveldb
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
Expand Down Expand Up @@ -234,11 +219,6 @@ if(HAVE_CLANG_THREAD_SAFETY)
-Werror -Wthread-safety)
endif(HAVE_CLANG_THREAD_SAFETY)

# TODO(costan): This is only needed for port_posix.
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(leveldb Threads::Threads)

if(HAVE_CRC32C)
target_link_libraries(leveldb crc32c)
endif(HAVE_CRC32C)
Expand All @@ -249,6 +229,10 @@ if(HAVE_TCMALLOC)
target_link_libraries(leveldb tcmalloc)
endif(HAVE_TCMALLOC)

# Needed by port_stdcxx.h
find_package(Threads REQUIRED)
target_link_libraries(leveldb Threads::Threads)

add_executable(leveldbutil
"${PROJECT_SOURCE_DIR}/db/leveldbutil.cc"
)
Expand All @@ -271,14 +255,6 @@ if(LEVELDB_BUILD_TESTS)

"${test_file}"
)
if(BUILD_SHARED_LIBS)
# Port functions aren't exposed in the shared library build.
target_sources("${test_target_name}"
PRIVATE
$<TARGET_OBJECTS:leveldb_port_posix>
)
endif(BUILD_SHARED_LIBS)

target_link_libraries("${test_target_name}" leveldb)
target_compile_definitions("${test_target_name}"
PRIVATE
Expand Down Expand Up @@ -351,14 +327,6 @@ if(LEVELDB_BUILD_BENCHMARKS)

"${bench_file}"
)
if(BUILD_SHARED_LIBS)
# Port functions aren't exposed in the shared library build.
target_sources("${bench_target_name}"
PRIVATE
$<TARGET_OBJECTS:leveldb_port_posix>
)
endif(BUILD_SHARED_LIBS)

target_link_libraries("${bench_target_name}" leveldb)
target_compile_definitions("${bench_target_name}"
PRIVATE
Expand Down
2 changes: 1 addition & 1 deletion port/README
Original file line number Diff line number Diff line change
Expand Up @@ -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.

2 changes: 1 addition & 1 deletion port/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
53 changes: 0 additions & 53 deletions port/port_posix.cc

This file was deleted.

74 changes: 42 additions & 32 deletions port/port_posix.h → port/port_stdcxx.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -24,62 +22,75 @@

#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 {

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) {
Expand All @@ -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
Expand All @@ -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_
6 changes: 6 additions & 0 deletions util/env_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
#include "util/posix_logger.h"
#include "util/env_posix_test_helper.h"

// HAVE_FDATASYNC is defined in the auto-generated port_config.h, which is
// included by port_stdcxx.h.
#if !HAVE_FDATASYNC
#define fdatasync fsync
#endif // !HAVE_FDATASYNC

namespace leveldb {

namespace {
Expand Down

0 comments on commit d177a02

Please sign in to comment.