Skip to content

Commit

Permalink
Remove static initializer; fix endian-ness detection; fix build on
Browse files Browse the repository at this point in the history
various platforms; improve android port speed.

Avoid static initializer by using a new portability interface for
thread-safe lazy initialization.  Custom ports will need to be
extended to implement InitOnce/OnceType/LEVELDB_ONCE_INIT.

Fix endian-ness detection (fixes Powerpc builds).

Build related fixes:
- Support platforms that have unversioned shared libraries.
- Fix IOS build rules.

Android improvements
- Speed up atomic pointers
- Share more code with port_posix.

Do not spin in a tight loop attempting compactions if the file system
is inaccessible (e.g., if kerberos tickets have expired or if it is out
of space).
  • Loading branch information
ghemawat committed May 30, 2012
1 parent 85584d4 commit 075a35a
Show file tree
Hide file tree
Showing 18 changed files with 283 additions and 62 deletions.
27 changes: 18 additions & 9 deletions Makefile
Expand Up @@ -3,8 +3,6 @@
# found in the LICENSE file. See the AUTHORS file for names of contributors.

# Inherit some settings from environment variables, if available
CXX ?= g++
CC ?= gcc
INSTALL_PATH ?= $(CURDIR)

#-----------------------------------------------
Expand Down Expand Up @@ -63,21 +61,31 @@ default: all

# Should we build shared libraries?
ifneq ($(PLATFORM_SHARED_EXT),)

ifneq ($(PLATFORM_SHARED_VERSIONED),true)
SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
SHARED2 = $(SHARED1)
SHARED3 = $(SHARED1)
SHARED = $(SHARED1)
else
# Update db.h if you change these.
SHARED_MAJOR = 1
SHARED_MINOR = 4
SHARED1 = libleveldb.$(PLATFORM_SHARED_EXT)
SHARED2 = $(SHARED1).$(SHARED_MAJOR)
SHARED3 = $(SHARED1).$(SHARED_MAJOR).$(SHARED_MINOR)
SHARED = $(SHARED1) $(SHARED2) $(SHARED3)
$(SHARED3):
$(CXX) $(LDFLAGS) $(PLATFORM_SHARED_LDFLAGS)$(INSTALL_PATH)/$(SHARED2) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(SOURCES) -o $(SHARED3)
$(SHARED2): $(SHARED3)
ln -fs $(SHARED3) $(SHARED2)
$(SHARED1): $(SHARED3)
ln -fs $(SHARED3) $(SHARED1)
$(SHARED2): $(SHARED3)
ln -fs $(SHARED3) $(SHARED2)
endif

$(SHARED3):
$(CXX) $(LDFLAGS) $(PLATFORM_SHARED_LDFLAGS)$(SHARED2) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(SOURCES) -o $(SHARED3)

endif # PLATFORM_SHARED_EXT

all: $(SHARED) $(LIBRARY)

check: all $(PROGRAMS) $(TESTS)
Expand Down Expand Up @@ -164,9 +172,10 @@ memenv_test : helpers/memenv/memenv_test.o $(MEMENVLIBRARY) $(LIBRARY) $(TESTHAR
ifeq ($(PLATFORM), IOS)
# For iOS, create universal object files to be used on both the simulator and
# a device.
SIMULATORROOT=/Developer/Platforms/iPhoneSimulator.platform/Developer
DEVICEROOT=/Developer/Platforms/iPhoneOS.platform/Developer
IOSVERSION=$(shell defaults read /Developer/Platforms/iPhoneOS.platform/version CFBundleShortVersionString)
PLATFORMSROOT=/Applications/Xcode.app/Contents/Developer/Platforms
SIMULATORROOT=$(PLATFORMSROOT)/iPhoneSimulator.platform/Developer
DEVICEROOT=$(PLATFORMSROOT)/iPhoneOS.platform/Developer
IOSVERSION=$(shell defaults read $(PLATFORMSROOT)/iPhoneOS.platform/version CFBundleShortVersionString)

.cc.o:
mkdir -p ios-x86/$(dir $@)
Expand Down
37 changes: 28 additions & 9 deletions build_detect_platform
Expand Up @@ -4,25 +4,38 @@
# argument, which in turn gets read while processing Makefile.
#
# The output will set the following variables:
# CC C Compiler path
# CXX C++ Compiler path
# PLATFORM_LDFLAGS Linker flags
# PLATFORM_SHARED_EXT Extension for shared libraries
# PLATFORM_SHARED_LDFLAGS Flags for building shared library
# PLATFORM_SHARED_CFLAGS Flags for compiling objects for shared library
# PLATFORM_CCFLAGS C compiler flags
# PLATFORM_CXXFLAGS C++ compiler flags. Will contain:
# -DLEVELDB_PLATFORM_POSIX if cstdatomic is present
# -DLEVELDB_PLATFORM_NOATOMIC if it is not
# PLATFORM_SHARED_VERSIONED Set to 'true' if platform supports versioned
# shared libraries, empty otherwise.
#
# The PLATFORM_CCFLAGS and PLATFORM_CXXFLAGS might include the following:
#
# -DLEVELDB_CSTDATOMIC_PRESENT if <cstdatomic> is present
# -DLEVELDB_PLATFORM_POSIX for Posix-based platforms
# -DSNAPPY if the Snappy library is present
#

OUTPUT=$1
if test -z "$OUTPUT"; then
echo "usage: $0 <output-filename>"
echo "usage: $0 <output-filename>" >&2
exit 1
fi

# Delete existing output, if it exists
rm -f $OUTPUT
touch $OUTPUT

if test -z "$CC"; then
CC=cc
fi

if test -z "$CXX"; then
CXX=g++
fi
Expand All @@ -33,12 +46,14 @@ if test -z "$TARGET_OS"; then
fi

COMMON_FLAGS=
CROSS_COMPILE=
PLATFORM_CCFLAGS=
PLATFORM_CXXFLAGS=
PLATFORM_LDFLAGS=
PLATFORM_SHARED_EXT="so"
PLATFORM_SHARED_LDFLAGS="-shared -Wl,-soname -Wl,"
PLATFORM_SHARED_CFLAGS="-fPIC"
PLATFORM_SHARED_VERSIONED=true

# On GCC, we pick libc's memcmp over GCC's memcmp via -fno-builtin-memcmp
case "$TARGET_OS" in
Expand Down Expand Up @@ -86,13 +101,14 @@ case "$TARGET_OS" in
PORT_FILE=port/port_posix.cc
;;
OS_ANDROID_CROSSCOMPILE)
PLATFORM="$TARGET_OS"
COMMON_FLAGS=""
PLATFORM_LDFLAGS=""
PORT_FILE=port/port_android.cc
PLATFORM=OS_ANDROID
COMMON_FLAGS="-fno-builtin-memcmp -D_REENTRANT -DOS_ANDROID -DLEVELDB_PLATFORM_POSIX"
PLATFORM_LDFLAGS="" # All pthread features are in the Android C library
PORT_FILE=port/port_posix.cc
CROSS_COMPILE=true
;;
*)
echo "Unknown platform!"
echo "Unknown platform!" >&2
exit 1
esac

Expand All @@ -112,7 +128,7 @@ set +f # re-enable globbing
echo "SOURCES=$PORTABLE_FILES $PORT_FILE" >> $OUTPUT
echo "MEMENV_SOURCES=helpers/memenv/memenv.cc" >> $OUTPUT

if [ "$PLATFORM" = "OS_ANDROID_CROSSCOMPILE" ]; then
if [ "$CROSS_COMPILE" = "true" ]; then
# Cross-compiling; do not try any compilation tests.
true
else
Expand Down Expand Up @@ -151,10 +167,13 @@ fi
PLATFORM_CCFLAGS="$PLATFORM_CCFLAGS $COMMON_FLAGS"
PLATFORM_CXXFLAGS="$PLATFORM_CXXFLAGS $COMMON_FLAGS"

echo "CC=$CC" >> $OUTPUT
echo "CXX=$CXX" >> $OUTPUT
echo "PLATFORM=$PLATFORM" >> $OUTPUT
echo "PLATFORM_LDFLAGS=$PLATFORM_LDFLAGS" >> $OUTPUT
echo "PLATFORM_CCFLAGS=$PLATFORM_CCFLAGS" >> $OUTPUT
echo "PLATFORM_CXXFLAGS=$PLATFORM_CXXFLAGS" >> $OUTPUT
echo "PLATFORM_SHARED_CFLAGS=$PLATFORM_SHARED_CFLAGS" >> $OUTPUT
echo "PLATFORM_SHARED_EXT=$PLATFORM_SHARED_EXT" >> $OUTPUT
echo "PLATFORM_SHARED_LDFLAGS=$PLATFORM_SHARED_LDFLAGS" >> $OUTPUT
echo "PLATFORM_SHARED_VERSIONED=$PLATFORM_SHARED_VERSIONED" >> $OUTPUT
11 changes: 10 additions & 1 deletion db/c_test.c
Expand Up @@ -19,6 +19,13 @@ static void StartPhase(const char* name) {
phase = name;
}

static const char* GetTempDir(void) {
const char* ret = getenv("TEST_TMPDIR");
if (ret == NULL || ret[0] == '\0')
ret = "/tmp";
return ret;
}

#define CheckNoError(err) \
if ((err) != NULL) { \
fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, (err)); \
Expand Down Expand Up @@ -158,7 +165,9 @@ int main(int argc, char** argv) {
char* err = NULL;
int run = -1;

snprintf(dbname, sizeof(dbname), "/tmp/leveldb_c_test-%d",
snprintf(dbname, sizeof(dbname),
"%s/leveldb_c_test-%d",
GetTempDir(),
((int) geteuid()));

StartPhase("create_objects");
Expand Down
10 changes: 9 additions & 1 deletion db/db_bench.cc
Expand Up @@ -100,7 +100,7 @@ static int FLAGS_bloom_bits = -1;
static bool FLAGS_use_existing_db = false;

// Use the db with the following name.
static const char* FLAGS_db = "/tmp/dbbench";
static const char* FLAGS_db = NULL;

namespace leveldb {

Expand Down Expand Up @@ -925,6 +925,7 @@ class Benchmark {
int main(int argc, char** argv) {
FLAGS_write_buffer_size = leveldb::Options().write_buffer_size;
FLAGS_open_files = leveldb::Options().max_open_files;
std::string default_db_path;

for (int i = 1; i < argc; i++) {
double d;
Expand Down Expand Up @@ -964,6 +965,13 @@ int main(int argc, char** argv) {
}
}

// Choose a location for the test database if none given with --db=<path>
if (FLAGS_db == NULL) {
leveldb::Env::Default()->GetTestDirectory(&default_db_path);
default_db_path += "/dbbench";
FLAGS_db = default_db_path.c_str();
}

leveldb::Benchmark benchmark;
benchmark.Run();
return 0;
Expand Down
23 changes: 19 additions & 4 deletions db/db_impl.cc
Expand Up @@ -608,8 +608,21 @@ void DBImpl::BackgroundCall() {
MutexLock l(&mutex_);
assert(bg_compaction_scheduled_);
if (!shutting_down_.Acquire_Load()) {
BackgroundCompaction();
Status s = BackgroundCompaction();
if (!s.ok()) {
// Wait a little bit before retrying background compaction in
// case this is an environmental problem and we do not want to
// chew up resources for failed compactions for the duration of
// the problem.
bg_cv_.SignalAll(); // In case a waiter can proceed despite the error
Log(options_.info_log, "Waiting after background compaction error: %s",
s.ToString().c_str());
mutex_.Unlock();
env_->SleepForMicroseconds(1000000);
mutex_.Lock();
}
}

bg_compaction_scheduled_ = false;

// Previous compaction may have produced too many files in a level,
Expand All @@ -618,12 +631,11 @@ void DBImpl::BackgroundCall() {
bg_cv_.SignalAll();
}

void DBImpl::BackgroundCompaction() {
Status DBImpl::BackgroundCompaction() {
mutex_.AssertHeld();

if (imm_ != NULL) {
CompactMemTable();
return;
return CompactMemTable();
}

Compaction* c;
Expand Down Expand Up @@ -698,6 +710,7 @@ void DBImpl::BackgroundCompaction() {
}
manual_compaction_ = NULL;
}
return status;
}

void DBImpl::CleanupCompaction(CompactionState* compact) {
Expand Down Expand Up @@ -1263,6 +1276,8 @@ Status DBImpl::MakeRoomForWrite(bool force) {
WritableFile* lfile = NULL;
s = env_->NewWritableFile(LogFileName(dbname_, new_log_number), &lfile);
if (!s.ok()) {
// Avoid chewing through file number space in a tight loop.
versions_->ReuseFileNumber(new_log_number);
break;
}
delete log_;
Expand Down
2 changes: 1 addition & 1 deletion db/db_impl.h
Expand Up @@ -94,7 +94,7 @@ class DBImpl : public DB {
void MaybeScheduleCompaction();
static void BGWork(void* db);
void BackgroundCall();
void BackgroundCompaction();
Status BackgroundCompaction();
void CleanupCompaction(CompactionState* compact);
Status DoCompactionWork(CompactionState* compact);

Expand Down

0 comments on commit 075a35a

Please sign in to comment.