Last active
December 27, 2015 16:29
-
-
Save rioki/7354980 to your computer and use it in GitHub Desktop.
leveldb Windows port
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Detects OS we're compiling on and outputs a file specified by the first | |
# 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_LIBS Libraries flags | |
# PLATFORM_SHARED_EXT Extension for shared libraries | |
# PLATFORM_SHARED_LDFLAGS Flags for building shared library | |
# This flag is embedded just before the name | |
# of the shared library without intervening spaces | |
# PLATFORM_SHARED_CFLAGS Flags for compiling objects for shared library | |
# PLATFORM_CCFLAGS C compiler flags | |
# PLATFORM_CXXFLAGS C++ compiler flags. Will contain: | |
# 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 | |
PREFIX=$2 | |
if test -z "$OUTPUT" || test -z "$PREFIX"; then | |
echo "usage: $0 <output-filename> <directory_prefix>" >&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 | |
if test -z "$TMPDIR"; then | |
TMPDIR=/tmp | |
fi | |
# Detect OS | |
if test -z "$TARGET_OS"; then | |
TARGET_OS=`uname -s` | |
fi | |
COMMON_FLAGS= | |
CROSS_COMPILE= | |
PLATFORM_CCFLAGS= | |
PLATFORM_CXXFLAGS= | |
PLATFORM_LDFLAGS= | |
PLATFORM_LIBS= | |
PLATFORM_SHARED_EXT="so" | |
PLATFORM_SHARED_LDFLAGS="-shared -Wl,-soname -Wl," | |
PLATFORM_SHARED_CFLAGS="-fPIC" | |
PLATFORM_SHARED_VERSIONED=true | |
MEMCMP_FLAG= | |
if [ "$CXX" = "g++" ]; then | |
# Use libc's memcmp instead of GCC's memcmp. This results in ~40% | |
# performance improvement on readrandom under gcc 4.4.3 on Linux/x86. | |
MEMCMP_FLAG="-fno-builtin-memcmp" | |
fi | |
case "$TARGET_OS" in | |
Darwin) | |
PLATFORM=OS_MACOSX | |
COMMON_FLAGS="$MEMCMP_FLAG -DOS_MACOSX -DLEVELDB_PLATFORM_POSIX" | |
PLATFORM_SHARED_EXT=dylib | |
[ -z "$INSTALL_PATH" ] && INSTALL_PATH=`pwd` | |
PLATFORM_SHARED_LDFLAGS="-dynamiclib -install_name $INSTALL_PATH/" | |
PORT_FILE=port/port_posix.cc | |
;; | |
Linux) | |
PLATFORM=OS_LINUX | |
COMMON_FLAGS="$MEMCMP_FLAG -pthread -DOS_LINUX -DLEVELDB_PLATFORM_POSIX" | |
PLATFORM_LDFLAGS="-pthread" | |
PORT_FILE=port/port_posix.cc | |
;; | |
SunOS) | |
PLATFORM=OS_SOLARIS | |
COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_SOLARIS -DLEVELDB_PLATFORM_POSIX" | |
PLATFORM_LIBS="-lpthread -lrt" | |
PORT_FILE=port/port_posix.cc | |
;; | |
FreeBSD) | |
PLATFORM=OS_FREEBSD | |
COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_FREEBSD -DLEVELDB_PLATFORM_POSIX" | |
PLATFORM_LIBS="-lpthread" | |
PORT_FILE=port/port_posix.cc | |
;; | |
NetBSD) | |
PLATFORM=OS_NETBSD | |
COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_NETBSD -DLEVELDB_PLATFORM_POSIX" | |
PLATFORM_LIBS="-lpthread -lgcc_s" | |
PORT_FILE=port/port_posix.cc | |
;; | |
OpenBSD) | |
PLATFORM=OS_OPENBSD | |
COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_OPENBSD -DLEVELDB_PLATFORM_POSIX" | |
PLATFORM_LDFLAGS="-pthread" | |
PORT_FILE=port/port_posix.cc | |
;; | |
DragonFly) | |
PLATFORM=OS_DRAGONFLYBSD | |
COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_DRAGONFLYBSD -DLEVELDB_PLATFORM_POSIX" | |
PLATFORM_LIBS="-lpthread" | |
PORT_FILE=port/port_posix.cc | |
;; | |
OS_ANDROID_CROSSCOMPILE) | |
PLATFORM=OS_ANDROID | |
COMMON_FLAGS="$MEMCMP_FLAG -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 | |
;; | |
HP-UX) | |
PLATFORM=OS_HPUX | |
COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_HPUX -DLEVELDB_PLATFORM_POSIX" | |
PLATFORM_LDFLAGS="-pthread" | |
PORT_FILE=port/port_posix.cc | |
# man ld: +h internal_name | |
PLATFORM_SHARED_LDFLAGS="-shared -Wl,+h -Wl," | |
;; | |
MINGW32*) | |
PLATFORM=OS_WINDOWS | |
COMMON_FLAGS="$MEMCMP_FLAG -DOS_WINDOWS -DLEVELDB_PLATFORM_WINDOWS -D_WIN32_WINNT=0x0600 -DWIN32_LEAN_AND_MEAN" | |
# PLATFORM_LDFLAGS="" | |
PLATFORM_SHARED_CFLAGS="" | |
PORT_FILE=port/port_windows.cc | |
;; | |
*) | |
echo "Unknown platform!" >&2 | |
exit 1 | |
esac | |
# We want to make a list of all cc files within util, db, table, and helpers | |
# except for the test and benchmark files. By default, find will output a list | |
# of all files matching either rule, so we need to append -print to make the | |
# prune take effect. | |
DIRS="$PREFIX/db $PREFIX/util $PREFIX/table" | |
set -f # temporarily disable globbing so that our patterns aren't expanded | |
PRUNE_TEST="-name *test*.cc -prune" | |
PRUNE_BENCH="-name *_bench.cc -prune" | |
PRUNE_TOOL="-name leveldb_main.cc -prune" | |
PORTABLE_FILES=`find $DIRS $PRUNE_TEST -o $PRUNE_BENCH -o $PRUNE_TOOL -o -name '*.cc' -print | sort | sed "s,^$PREFIX/,," | tr "\n" " "` | |
set +f # re-enable globbing | |
# The sources consist of the portable files, plus the platform-specific port | |
# file. | |
echo "SOURCES=$PORTABLE_FILES $PORT_FILE" >> $OUTPUT | |
echo "MEMENV_SOURCES=helpers/memenv/memenv.cc" >> $OUTPUT | |
if [ "$CROSS_COMPILE" = "true" ]; then | |
# Cross-compiling; do not try any compilation tests. | |
true | |
else | |
CXXOUTPUT="${TMPDIR}/leveldb_build_detect_platform-cxx.$$" | |
# If -std=c++0x works, use <cstdatomic>. Otherwise use port_posix.h. | |
$CXX $CXXFLAGS -std=c++0x -x c++ - -o $CXXOUTPUT 2>/dev/null <<EOF | |
#include <cstdatomic> | |
int main() {} | |
EOF | |
if [ "$?" = 0 ]; then | |
COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_CSTDATOMIC_PRESENT" | |
PLATFORM_CXXFLAGS="-std=c++0x" | |
else | |
COMMON_FLAGS="$COMMON_FLAGS" | |
fi | |
# Test whether Snappy library is installed | |
# http://code.google.com/p/snappy/ | |
$CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT 2>/dev/null <<EOF | |
#include <snappy.h> | |
int main() {} | |
EOF | |
if [ "$?" = 0 ]; then | |
COMMON_FLAGS="$COMMON_FLAGS -DSNAPPY" | |
PLATFORM_LIBS="$PLATFORM_LIBS -lsnappy" | |
fi | |
# Test whether tcmalloc is available | |
$CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT -ltcmalloc 2>/dev/null <<EOF | |
int main() {} | |
EOF | |
if [ "$?" = 0 ]; then | |
PLATFORM_LIBS="$PLATFORM_LIBS -ltcmalloc" | |
fi | |
rm -f $CXXOUTPUT 2>/dev/null | |
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_LIBS=$PLATFORM_LIBS" >> $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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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. | |
#ifndef STORAGE_LEVELDB_PORT_PORT_H_ | |
#define STORAGE_LEVELDB_PORT_PORT_H_ | |
#include <string.h> | |
// Include the appropriate platform specific file below. If you are | |
// 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" | |
#elif defined(LEVELDB_PLATFORM_WINDOWS) | |
# include "port/port_windows.h" | |
#elif defined(LEVELDB_PLATFORM_CHROMIUM) | |
# include "port/port_chromium.h" | |
#endif | |
#endif // STORAGE_LEVELDB_PORT_PORT_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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_windows.h" | |
#include <windef.h> | |
namespace leveldb { | |
namespace port { | |
Mutex::Mutex() { | |
InitializeCriticalSection(&cs); | |
} | |
Mutex::~Mutex() { | |
DeleteCriticalSection(&cs); | |
} | |
void Mutex::Lock() { | |
EnterCriticalSection(&cs); | |
} | |
void Mutex::Unlock() { | |
LeaveCriticalSection(&cs); | |
} | |
CondVar::CondVar(Mutex* m) : | |
mu(m) { | |
sem1 = CreateSemaphore(NULL, 0, 10000, NULL); | |
sem2 = CreateSemaphore(NULL, 0, 10000, NULL); | |
} | |
CondVar::~CondVar() { | |
CloseHandle(sem1); | |
CloseHandle(sem2); | |
} | |
void CondVar::Wait() { | |
waiting_mutex.Lock(); | |
waiting++; | |
waiting_mutex.Unlock(); | |
mu->Unlock(); | |
WaitForSingleObject(sem1, INFINITE); | |
ReleaseSemaphore(sem2, 1, NULL); | |
mu->Lock(); | |
} | |
void CondVar::Signal() { | |
waiting_mutex.Lock(); | |
if (waiting > 0) { | |
waiting--; | |
ReleaseSemaphore(sem1, 1, NULL); | |
WaitForSingleObject(sem2, INFINITE); | |
} | |
waiting_mutex.Unlock(); | |
} | |
void CondVar::SignalAll() { | |
waiting_mutex.Lock(); | |
for(long i = 0; i < waiting; i++) { | |
ReleaseSemaphore(sem1, 1, NULL); | |
while(waiting > 0) { | |
waiting--; | |
WaitForSingleObject(sem2, INFINITE); | |
} | |
} | |
waiting_mutex.Unlock(); | |
} | |
typedef void (*ini_fun_t)(); | |
BOOL InitOnce_Impl(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext) { | |
ini_fun_t initializer = reinterpret_cast<ini_fun_t>(Parameter); | |
initializer(); | |
} | |
void InitOnce(port::OnceType* once, void (*initializer)()) { | |
InitOnceExecuteOnce(once, &InitOnce_Impl, reinterpret_cast<void*>(initializer), NULL); | |
} | |
} // namespace port | |
} // namespace leveldb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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. | |
// | |
#ifndef STORAGE_LEVELDB_PORT_PORT_WINDOWS_H_ | |
#define STORAGE_LEVELDB_PORT_PORT_WINDOWS_H_ | |
#include <string> | |
#include <windows.h> | |
#include "port/atomic_pointer.h" | |
namespace leveldb { | |
namespace port { | |
static const bool kLittleEndian = true; | |
// ------------------ Threading ------------------- | |
class Mutex { | |
public: | |
Mutex(); | |
~Mutex(); | |
void Lock(); | |
void Unlock(); | |
void AssertHeld() {} | |
private: | |
CRITICAL_SECTION cs; | |
}; | |
class CondVar { | |
public: | |
explicit CondVar(Mutex* mu); | |
~CondVar(); | |
void Wait(); | |
void Signal(); | |
void SignalAll(); | |
private: | |
Mutex* mu; | |
Mutex waiting_mutex; | |
long waiting; | |
HANDLE sem1; | |
HANDLE sem2; | |
}; | |
typedef INIT_ONCE OnceType; | |
#define LEVELDB_ONCE_INIT INIT_ONCE_STATIC_INIT | |
extern void InitOnce(port::OnceType*, void (*initializer)()); | |
inline bool Snappy_Compress(const char* input, size_t length, | |
::std::string* output) { | |
#ifdef SNAPPY | |
output->resize(snappy::MaxCompressedLength(length)); | |
size_t outlen; | |
snappy::RawCompress(input, length, &(*output)[0], &outlen); | |
output->resize(outlen); | |
return true; | |
#endif | |
return false; | |
} | |
inline bool Snappy_GetUncompressedLength(const char* input, size_t length, | |
size_t* result) { | |
#ifdef SNAPPY | |
return snappy::GetUncompressedLength(input, length, result); | |
#else | |
return false; | |
#endif | |
} | |
inline bool Snappy_Uncompress(const char* input, size_t length, | |
char* output) { | |
#ifdef SNAPPY | |
return snappy::RawUncompress(input, length, output); | |
#else | |
return false; | |
#endif | |
} | |
inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { | |
return false; | |
} | |
} // namespace port | |
} // namespace leveldb | |
#endif // STORAGE_LEVELDB_PORT_PORT_WINDOWS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 "util/windows_logger.h" | |
#include <windows.h> | |
namespace leveldb { | |
void WinLogger::Logv(const char* format, va_list ap) { | |
const uint64_t thread_id = static_cast<uint64_t>(::GetCurrentThreadId()); | |
// We try twice: the first time with a fixed-size stack allocated buffer, | |
// and the second time with a much larger dynamically allocated buffer. | |
char buffer[500]; | |
for (int iter = 0; iter < 2; iter++) { | |
char* base; | |
int bufsize; | |
if (iter == 0) { | |
bufsize = sizeof(buffer); | |
base = buffer; | |
} else { | |
bufsize = 30000; | |
base = new char[bufsize]; | |
} | |
char* p = base; | |
char* limit = base + bufsize; | |
SYSTEMTIME st; | |
// GetSystemTime returns UTC time, we want local time! | |
::GetLocalTime(&st); | |
p += _snprintf_s(p, limit - p, _TRUNCATE, | |
"%04d/%02d/%02d-%02d:%02d:%02d.%03d %llx ", | |
st.wYear, | |
st.wMonth, | |
st.wDay, | |
st.wHour, | |
st.wMinute, | |
st.wSecond, | |
st.wMilliseconds, | |
static_cast<long long unsigned int>(thread_id)); | |
// Print the message | |
if (p < limit) { | |
va_list backup_ap = ap; | |
p += vsnprintf(p, limit - p, format, backup_ap); | |
va_end(backup_ap); | |
} | |
// Truncate to available space if necessary | |
if (p >= limit) { | |
if (iter == 0) { | |
continue; // Try again with larger buffer | |
} else { | |
p = limit - 1; | |
} | |
} | |
// Add newline if necessary | |
if (p == base || p[-1] != '\n') { | |
*p++ = '\n'; | |
} | |
assert(p <= limit); | |
fwrite(base, 1, p - base, file_); | |
fflush(file_); | |
if (base != buffer) { | |
delete[] base; | |
} | |
break; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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. | |
// Logger implementation for Windows | |
#ifndef STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ | |
#define STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ | |
#include <stdio.h> | |
#include "leveldb/env.h" | |
namespace leveldb { | |
class WinLogger : public Logger { | |
private: | |
FILE* file_; | |
public: | |
explicit WinLogger(FILE* f) : file_(f) { assert(file_); } | |
virtual ~WinLogger() { | |
fclose(file_); | |
} | |
virtual void Logv(const char* format, va_list ap); | |
}; | |
} | |
#endif // STORAGE_LEVELDB_UTIL_WIN_LOGGER_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment