Merge pull request #2634 from skunkwerks/feature/add-freebsd
support FreeBSD
This commit is contained in:
commit
9f2c07a97c
|
@ -146,6 +146,10 @@ set(SEED "0x${SEED_}" CACHE STRING "Random seed for testing")
|
|||
# components
|
||||
################################################################################
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
include_directories(/usr/local/include)
|
||||
endif()
|
||||
|
||||
include(CompileBoost)
|
||||
add_subdirectory(flow)
|
||||
add_subdirectory(fdbrpc)
|
||||
|
@ -173,6 +177,10 @@ else()
|
|||
include(CPack)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
add_link_options(-lexecinfo)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# process compile commands for IDE
|
||||
################################################################################
|
||||
|
|
31
README.md
31
README.md
|
@ -123,6 +123,37 @@ cmake -G Xcode -DOPEN_FOR_IDE=ON <FDB_SOURCE_DIRECTORY>
|
|||
You should create a second build-directory which you will use for building
|
||||
(probably with make or ninja) and debugging.
|
||||
|
||||
#### FreeBSD
|
||||
|
||||
1. Check out this repo on your server.
|
||||
1. Install compile-time dependencies from ports.
|
||||
1. (Optional) Use tmpfs & ccache for significantly faster repeat builds
|
||||
1. (Optional) Install a [JDK](https://www.freshports.org/java/openjdk8/)
|
||||
for Java Bindings. FoundationDB currently builds with Java 8.
|
||||
1. Navigate to the directory where you checked out the foundationdb
|
||||
repo.
|
||||
1. Build from source.
|
||||
|
||||
```shell
|
||||
sudo pkg install -r FreeBSD \
|
||||
shells/bash devel/cmake devel/ninja devel/ccache \
|
||||
lang/mono lang/python3 \
|
||||
devel/boost-libs devel/libeio \
|
||||
security/openssl
|
||||
mkdir .build && cd .build
|
||||
cmake -G Ninja \
|
||||
-DUSE_CCACHE=on \
|
||||
-DDISABLE_TLS=off \
|
||||
-DUSE_DTRACE=off \
|
||||
..
|
||||
ninja -j 10
|
||||
# run fast tests
|
||||
ctest -L fast
|
||||
# run all tests
|
||||
ctest --output-on-failure -v
|
||||
```
|
||||
|
||||
|
||||
### Linux
|
||||
|
||||
There are no special requirements for Linux. A docker image can be pulled from
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
######################################################
|
||||
#
|
||||
# FoundationDB Binding Test Script
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
LOGGING_LEVEL=WARNING
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ def write_windows_asm(asmfile, functions):
|
|||
def write_unix_asm(asmfile, functions, prefix):
|
||||
asmfile.write(".intel_syntax noprefix\n")
|
||||
|
||||
if platform == "linux":
|
||||
if platform == "linux" or platform == "freebsd":
|
||||
asmfile.write("\n.data\n")
|
||||
for f in functions:
|
||||
asmfile.write("\t.extern fdb_api_ptr_%s\n" % f)
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
#if defined(__linux__)
|
||||
#include <linux/limits.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <sys/stat.h>
|
||||
#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC_FAST
|
||||
#elif defined(__APPLE__)
|
||||
#include <sys/syslimits.h>
|
||||
#define CLOCK_MONOTONIC_COARSE CLOCK_MONOTONIC
|
||||
|
|
|
@ -25,6 +25,9 @@ platform=$(uname)
|
|||
if [[ "${platform}" == "Darwin" ]] ; then
|
||||
FDBLIBDIR="${FDBLIBDIR:-/usr/local/lib}"
|
||||
libfdbc="libfdb_c.dylib"
|
||||
elif [[ "${platform}" == "FreeBSD" ]] ; then
|
||||
FDBLIBDIR="${FDBLIBDIR:-/lib}"
|
||||
libfdbc="libfdb_c.so"
|
||||
elif [[ "${platform}" == "Linux" ]] ; then
|
||||
libfdbc="libfdb_c.so"
|
||||
custom_libdir="${FDBLIBDIR:-}"
|
||||
|
@ -248,8 +251,11 @@ else
|
|||
:
|
||||
elif [[ "${status}" -eq 0 ]] ; then
|
||||
echo "Building generated files."
|
||||
if [[ "${platform}" == "FreeBSD" ]] ; then
|
||||
cmd=( 'gmake' '-C' "${fdbdir}" 'bindings/c/foundationdb/fdb_c_options.g.h' )
|
||||
else
|
||||
cmd=( 'make' '-C' "${fdbdir}" 'bindings/c/foundationdb/fdb_c_options.g.h' )
|
||||
|
||||
fi
|
||||
echo "${cmd[*]}"
|
||||
if ! "${cmd[@]}" ; then
|
||||
let status="${status} + 1"
|
||||
|
|
|
@ -1231,6 +1231,8 @@ if platform.system() == 'Windows':
|
|||
capi_name = 'fdb_c.dll'
|
||||
elif platform.system() == 'Linux':
|
||||
capi_name = 'libfdb_c.so'
|
||||
elif platform.system() == 'FreeBSD':
|
||||
capi_name = 'libfdb_c.so'
|
||||
elif platform.system() == 'Darwin':
|
||||
capi_name = 'libfdb_c.dylib'
|
||||
elif sys.platform == 'win32':
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
include(CompilerChecks)
|
||||
|
||||
env_set(USE_GPERFTOOLS OFF BOOL "Use gperfools for profiling")
|
||||
env_set(USE_DTRACE ON BOOL "Enable dtrace probes on supported platforms")
|
||||
env_set(USE_VALGRIND OFF BOOL "Compile for valgrind usage")
|
||||
env_set(USE_VALGRIND_FOR_CTEST ${USE_VALGRIND} BOOL "Use valgrind for ctest")
|
||||
env_set(ALLOC_INSTRUMENTATION OFF BOOL "Instrument alloc")
|
||||
|
@ -255,7 +256,7 @@ else()
|
|||
check_symbol_exists(DTRACE_PROBE sys/sdt.h SUPPORT_DTRACE)
|
||||
check_symbol_exists(aligned_alloc stdlib.h HAS_ALIGNED_ALLOC)
|
||||
message(STATUS "Has aligned_alloc: ${HAS_ALIGNED_ALLOC}")
|
||||
if(SUPPORT_DTRACE)
|
||||
if((SUPPORT_DTRACE) AND (USE_DTRACE))
|
||||
add_compile_definitions(DTRACE_PROBES)
|
||||
endif()
|
||||
if(HAS_ALIGNED_ALLOC)
|
||||
|
|
|
@ -47,7 +47,8 @@ endif()
|
|||
set(WITH_JAVA OFF)
|
||||
find_package(JNI 1.8)
|
||||
find_package(Java 1.8 COMPONENTS Development)
|
||||
if(JNI_FOUND AND Java_FOUND AND Java_Development_FOUND)
|
||||
# leave FreeBSD JVM compat for later
|
||||
if(JNI_FOUND AND Java_FOUND AND Java_Development_FOUND AND NOT (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD"))
|
||||
set(WITH_JAVA ON)
|
||||
include(UseJava)
|
||||
enable_language(Java)
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
#include <linux/limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/event.h>
|
||||
#define O_EVTONLY O_RDONLY
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/event.h>
|
||||
#include <mach/mach.h>
|
||||
|
@ -78,7 +83,7 @@
|
|||
|
||||
#ifdef __linux__
|
||||
typedef fd_set* fdb_fd_set;
|
||||
#elif defined __APPLE__
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
typedef int fdb_fd_set;
|
||||
#endif
|
||||
|
||||
|
@ -89,7 +94,7 @@ void monitor_fd( fdb_fd_set list, int fd, int* maxfd, void* cmd ) {
|
|||
FD_SET( fd, list );
|
||||
if ( fd > *maxfd )
|
||||
*maxfd = fd;
|
||||
#elif defined __APPLE__
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
/* ignore maxfd */
|
||||
struct kevent ev;
|
||||
EV_SET( &ev, fd, EVFILT_READ, EV_ADD, 0, 0, cmd );
|
||||
|
@ -100,7 +105,7 @@ void monitor_fd( fdb_fd_set list, int fd, int* maxfd, void* cmd ) {
|
|||
void unmonitor_fd( fdb_fd_set list, int fd ) {
|
||||
#ifdef __linux__
|
||||
FD_CLR( fd, list );
|
||||
#elif defined __APPLE__
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
struct kevent ev;
|
||||
EV_SET( &ev, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL );
|
||||
kevent( list, &ev, 1, NULL, 0, NULL ); // FIXME: check?
|
||||
|
@ -194,7 +199,7 @@ const char* get_value_multi(const CSimpleIni& ini, const char* key, ...) {
|
|||
}
|
||||
|
||||
double timer() {
|
||||
#if defined(__linux__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return double(ts.tv_sec) + (ts.tv_nsec * 1e-9);
|
||||
|
@ -913,7 +918,7 @@ void read_child_output( Command* cmd, int pipe_idx, fdb_fd_set fds ) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
void watch_conf_dir( int kq, int* confd_fd, std::string confdir ) {
|
||||
struct kevent ev;
|
||||
std::string original = confdir;
|
||||
|
@ -1171,7 +1176,11 @@ int main(int argc, char** argv) {
|
|||
// testPathOps(); return -1;
|
||||
|
||||
std::string lockfile = "/var/run/fdbmonitor.pid";
|
||||
#ifdef __FreeBSD__
|
||||
std::string _confpath = "/usr/local/etc/foundationdb/foundationdb.conf";
|
||||
#else
|
||||
std::string _confpath = "/etc/foundationdb/foundationdb.conf";
|
||||
#endif
|
||||
|
||||
std::vector<const char *> additional_watch_paths;
|
||||
|
||||
|
@ -1266,12 +1275,12 @@ int main(int argc, char** argv) {
|
|||
#endif
|
||||
|
||||
if (daemonize) {
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
if (daemon(0, 0)) {
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
log_err("daemon", errno, "Unable to daemonize");
|
||||
|
@ -1330,7 +1339,7 @@ int main(int argc, char** argv) {
|
|||
signal(SIGHUP, signal_handler);
|
||||
signal(SIGINT, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
int kq = kqueue();
|
||||
if ( kq < 0 ) {
|
||||
log_err( "kqueue", errno, "Unable to create kqueue" );
|
||||
|
@ -1375,11 +1384,11 @@ int main(int argc, char** argv) {
|
|||
/* normal will be restored in our main loop in the call to
|
||||
pselect, but none blocks all signals while processing events */
|
||||
sigprocmask(SIG_SETMASK, &full_mask, &normal_mask);
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
sigprocmask(0, NULL, &normal_mask);
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
struct stat st_buf;
|
||||
struct timespec mtimespec;
|
||||
|
||||
|
@ -1438,7 +1447,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
load_conf(confpath.c_str(), uid, gid, &normal_mask, &rfds, &maxfd);
|
||||
reload_additional_watches = false;
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
load_conf( confpath.c_str(), uid, gid, &normal_mask, watched_fds, &maxfd );
|
||||
watch_conf_file( kq, &conff_fd, confpath.c_str() );
|
||||
watch_conf_dir( kq, &confd_fd, confdir );
|
||||
|
@ -1476,7 +1485,7 @@ int main(int argc, char** argv) {
|
|||
if(nfds == 0) {
|
||||
reload = true;
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
int nev = 0;
|
||||
if(timeout < 0) {
|
||||
nev = kevent( kq, NULL, 0, &ev, 1, NULL );
|
||||
|
|
|
@ -49,7 +49,16 @@ if(APPLE)
|
|||
list(APPEND FDBRPC_THIRD_PARTY_SRCS libcoroutine/asm.S)
|
||||
endif()
|
||||
if(NOT WIN32)
|
||||
list(APPEND FDBRPC_THIRD_PARTY_SRCS libcoroutine/context.c libeio/eio.c)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
find_library(EIO eio)
|
||||
if(EIO)
|
||||
list(APPEND FDBRPC_THIRD_PARTY_SRCS libcoroutine/context.c)
|
||||
else()
|
||||
list(APPEND FDBRPC_THIRD_PARTY_SRCS libcoroutine/context.c libeio/eio.c)
|
||||
endif()
|
||||
else()
|
||||
list(APPEND FDBRPC_THIRD_PARTY_SRCS libcoroutine/context.c libeio/eio.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(thirdparty STATIC ${FDBRPC_THIRD_PARTY_SRCS})
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* fdatasync(2) is available */
|
||||
#define HAVE_FDATASYNC 1
|
||||
|
||||
/* futimes(2) is available */
|
||||
#define HAVE_FUTIMES 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* fallocate(2) is available */
|
||||
/* #undef HAVE_LINUX_FALLOCATE */
|
||||
|
||||
/* Define to 1 if you have the <linux/fiemap.h> header file. */
|
||||
/* #undef HAVE_LINUX_FIEMAP_H */
|
||||
|
||||
/* Define to 1 if you have the <linux/fs.h> header file. */
|
||||
/* #undef HAVE_LINUX_FS_H */
|
||||
|
||||
/* splice/vmsplice/tee(2) are available */
|
||||
/* #undef HAVE_LINUX_SPLICE */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* posix_fadvise(2) is available */
|
||||
#define HAVE_POSIX_FADVISE 1
|
||||
|
||||
/* posix_madvise(2) is available */
|
||||
#define HAVE_POSIX_MADVISE 1
|
||||
|
||||
/* prctl(PR_SET_NAME) is available */
|
||||
/* #undef HAVE_PRCTL_SET_NAME */
|
||||
|
||||
/* readahead(2) is available (linux) */
|
||||
/* #undef HAVE_READAHEAD */
|
||||
|
||||
/* sendfile(2) is available and supported */
|
||||
#define HAVE_SENDFILE 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* sync_file_range(2) is available */
|
||||
/* #undef HAVE_SYNC_FILE_RANGE */
|
||||
|
||||
/* Define to 1 if you have the <sys/prctl.h> header file. */
|
||||
/* #undef HAVE_SYS_PRCTL_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* syscall(__NR_syncfs) is available */
|
||||
/* #undef HAVE_SYS_SYNCFS */
|
||||
|
||||
/* Define to 1 if you have the <sys/syscall.h> header file. */
|
||||
#define HAVE_SYS_SYSCALL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* utimes(2) is available */
|
||||
#define HAVE_UTIMES 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "libeio"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION ""
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# define _ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# define _TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.0"
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
|
@ -39,6 +39,8 @@
|
|||
|
||||
#ifdef __linux__
|
||||
#include "config.h.linux"
|
||||
#elif defined(__FreeBSD__)
|
||||
#include "config.h.FreeBSD"
|
||||
#elif defined(__APPLE__)
|
||||
#include "config.h.osx"
|
||||
#endif
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
|
||||
#include "fdbmonitor/SimpleIni.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
#include <execinfo.h>
|
||||
#include <signal.h>
|
||||
#ifdef ALLOC_INSTRUMENTATION
|
||||
|
@ -75,6 +75,7 @@
|
|||
#endif
|
||||
|
||||
#include "flow/SimpleOpt.h"
|
||||
#include <fstream>
|
||||
#include "flow/actorcompiler.h" // This must be the last #include.
|
||||
|
||||
// clang-format off
|
||||
|
@ -291,7 +292,7 @@ public:
|
|||
throw platform_error();
|
||||
}
|
||||
permission.set_permissions( &sa );
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
// There is nothing to do here, since the default permissions are fine
|
||||
#else
|
||||
#error Port me!
|
||||
|
@ -301,7 +302,7 @@ public:
|
|||
virtual ~WorldReadablePermissions() {
|
||||
#ifdef _WIN32
|
||||
LocalFree( sa.lpSecurityDescriptor );
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
// There is nothing to do here, since the default permissions are fine
|
||||
#else
|
||||
#error Port me!
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
#ifdef USE_GPERFTOOLS
|
||||
#include "gperftools/profiler.h"
|
||||
#include "gperftools/heap-profiler.h"
|
||||
|
@ -526,7 +528,7 @@ ACTOR Future<Void> registrationClient(
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(__linux__) && defined(USE_GPERFTOOLS)
|
||||
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
|
||||
//A set of threads that should be profiled
|
||||
std::set<std::thread::id> profiledThreads;
|
||||
|
||||
|
@ -538,7 +540,7 @@ int filter_in_thread(void *arg) {
|
|||
|
||||
//Enables the calling thread to be profiled
|
||||
void registerThreadForProfiling() {
|
||||
#if defined(__linux__) && defined(USE_GPERFTOOLS)
|
||||
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
|
||||
//Not sure if this is actually needed, but a call to backtrace was advised here:
|
||||
//http://groups.google.com/group/google-perftools/browse_thread/thread/0dfd74532e038eb8/2686d9f24ac4365f?pli=1
|
||||
profiledThreads.insert(std::this_thread::get_id());
|
||||
|
@ -552,7 +554,7 @@ void registerThreadForProfiling() {
|
|||
void updateCpuProfiler(ProfilerRequest req) {
|
||||
switch (req.type) {
|
||||
case ProfilerRequest::Type::GPROF:
|
||||
#if defined(__linux__) && defined(USE_GPERFTOOLS) && !defined(VALGRIND)
|
||||
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS) && !defined(VALGRIND)
|
||||
switch (req.action) {
|
||||
case ProfilerRequest::Action::ENABLE: {
|
||||
const char *path = (const char*)req.outputFile.begin();
|
||||
|
|
|
@ -94,6 +94,13 @@ elseif(WIN32)
|
|||
target_link_libraries(flow PUBLIC winmm.lib)
|
||||
target_link_libraries(flow PUBLIC psapi.lib)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
|
||||
set (FLOW_LIBS ${FLOW_LIBS} execinfo devstat)
|
||||
find_library(EIO eio)
|
||||
if(EIO)
|
||||
target_link_libraries(flow PUBLIC ${EIO})
|
||||
endif()
|
||||
endif()
|
||||
target_link_libraries(flow PRIVATE ${FLOW_LIBS})
|
||||
if(USE_VALGRIND)
|
||||
target_link_libraries(flow PUBLIC Valgrind)
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
#include <linux/mman.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#define FAST_ALLOCATOR_DEBUG 0
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -54,6 +58,8 @@
|
|||
#elif defined(__GNUG__)
|
||||
#ifdef __linux__
|
||||
#define INIT_SEG __attribute__ ((init_priority (1000)))
|
||||
#elif defined(__FreeBSD__)
|
||||
#define INIT_SEG __attribute__ ((init_priority (1000)))
|
||||
#elif defined(__APPLE__)
|
||||
#pragma message "init_priority is not supported on this platform; will this be a problem?"
|
||||
#define INIT_SEG
|
||||
|
|
|
@ -55,7 +55,7 @@ intptr_t g_stackYieldLimit = 0;
|
|||
|
||||
using namespace boost::asio::ip;
|
||||
|
||||
#if defined(__linux__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
#include <execinfo.h>
|
||||
|
||||
std::atomic<int64_t> net2RunLoopIterations(0);
|
||||
|
|
|
@ -104,6 +104,39 @@
|
|||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
/* Needed for processor affinity */
|
||||
#include <sys/sched.h>
|
||||
/* Needed for getProcessorTime and setpriority */
|
||||
#include <sys/syscall.h>
|
||||
/* Needed for setpriority */
|
||||
#include <sys/resource.h>
|
||||
/* Needed for crash handler */
|
||||
#include <sys/signal.h>
|
||||
/* Needed for proc info */
|
||||
#include <sys/user.h>
|
||||
/* Needed for vm info */
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/cpuset.h>
|
||||
#include <sys/resource.h>
|
||||
/* Needed for sysctl info */
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/fcntl.h>
|
||||
/* Needed for network info */
|
||||
#include <net/if.h>
|
||||
#include <net/if_mib.h>
|
||||
#include <net/if_var.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
/* Needed for device info */
|
||||
#include <devstat.h>
|
||||
#include <kvm.h>
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/uio.h>
|
||||
#include <sys/syslimits.h>
|
||||
|
@ -203,7 +236,7 @@ double getProcessorTimeThread() {
|
|||
throw platform_error();
|
||||
}
|
||||
return FiletimeAsInt64(ftKernel) / double(1e7) + FiletimeAsInt64(ftUser) / double(1e7);
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
return getProcessorTimeGeneric(RUSAGE_THREAD);
|
||||
#elif defined(__APPLE__)
|
||||
/* No RUSAGE_THREAD so we use the lower level interface */
|
||||
|
@ -255,6 +288,29 @@ uint64_t getResidentMemoryUsage() {
|
|||
|
||||
rssize *= sysconf(_SC_PAGESIZE);
|
||||
|
||||
return rssize;
|
||||
#elif defined(__FreeBSD__)
|
||||
uint64_t rssize = 0;
|
||||
|
||||
int status;
|
||||
pid_t ppid = getpid();
|
||||
int pidinfo[4];
|
||||
pidinfo[0] = CTL_KERN;
|
||||
pidinfo[1] = KERN_PROC;
|
||||
pidinfo[2] = KERN_PROC_PID;
|
||||
pidinfo[3] = (int)ppid;
|
||||
|
||||
struct kinfo_proc procstk;
|
||||
size_t len = sizeof(procstk);
|
||||
|
||||
status = sysctl(pidinfo, nitems(pidinfo), &procstk, &len, NULL, 0);
|
||||
if (status < 0){
|
||||
TraceEvent(SevError, "GetResidentMemoryUsage").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
rssize = (uint64_t)procstk.ki_rssize;
|
||||
|
||||
return rssize;
|
||||
#elif defined(_WIN32)
|
||||
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||
|
@ -292,6 +348,29 @@ uint64_t getMemoryUsage() {
|
|||
|
||||
vmsize *= sysconf(_SC_PAGESIZE);
|
||||
|
||||
return vmsize;
|
||||
#elif defined(__FreeBSD__)
|
||||
uint64_t vmsize = 0;
|
||||
|
||||
int status;
|
||||
pid_t ppid = getpid();
|
||||
int pidinfo[4];
|
||||
pidinfo[0] = CTL_KERN;
|
||||
pidinfo[1] = KERN_PROC;
|
||||
pidinfo[2] = KERN_PROC_PID;
|
||||
pidinfo[3] = (int)ppid;
|
||||
|
||||
struct kinfo_proc procstk;
|
||||
size_t len = sizeof(procstk);
|
||||
|
||||
status = sysctl(pidinfo, nitems(pidinfo), &procstk, &len, NULL, 0);
|
||||
if (status < 0){
|
||||
TraceEvent(SevError, "GetMemoryUsage").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
vmsize = (uint64_t)procstk.ki_size >> PAGE_SHIFT;
|
||||
|
||||
return vmsize;
|
||||
#elif defined(_WIN32)
|
||||
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||
|
@ -401,6 +480,52 @@ void getMachineRAMInfo(MachineRAMInfo& memInfo) {
|
|||
memInfo.available = 1024 * (std::max<int64_t>(0, (memFree-lowWatermark) + std::max(pageCache-lowWatermark, pageCache/2) + std::max(slabReclaimable-lowWatermark, slabReclaimable/2)) - usedSwap);
|
||||
}
|
||||
|
||||
memInfo.committed = memInfo.total - memInfo.available;
|
||||
#elif defined(__FreeBSD__)
|
||||
int status;
|
||||
|
||||
u_int page_size;
|
||||
u_int free_count;
|
||||
u_int active_count;
|
||||
u_int inactive_count;
|
||||
u_int wire_count;
|
||||
|
||||
size_t uint_size;
|
||||
|
||||
uint_size = sizeof(page_size);
|
||||
|
||||
status = sysctlbyname("vm.stats.vm.v_page_size", &page_size, &uint_size, NULL, 0);
|
||||
if (status < 0){
|
||||
TraceEvent(SevError, "GetMachineMemInfo").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
status = sysctlbyname("vm.stats.vm.v_free_count", &free_count, &uint_size, NULL, 0);
|
||||
if (status < 0){
|
||||
TraceEvent(SevError, "GetMachineMemInfo").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
status = sysctlbyname("vm.stats.vm.v_active_count", &active_count, &uint_size, NULL, 0);
|
||||
if (status < 0){
|
||||
TraceEvent(SevError, "GetMachineMemInfo").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
status = sysctlbyname("vm.stats.vm.v_inactive_count", &inactive_count, &uint_size, NULL, 0);
|
||||
if (status < 0){
|
||||
TraceEvent(SevError, "GetMachineMemInfo").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
status = sysctlbyname("vm.stats.vm.v_wire_count", &wire_count, &uint_size, NULL, 0);
|
||||
if (status < 0){
|
||||
TraceEvent(SevError, "GetMachineMemInfo").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
memInfo.total = (int64_t)((free_count + active_count + inactive_count + wire_count) * (u_int64_t)(page_size));
|
||||
memInfo.available = (int64_t)(free_count * (u_int64_t)(page_size));
|
||||
memInfo.committed = memInfo.total - memInfo.available;
|
||||
#elif defined(_WIN32)
|
||||
MEMORYSTATUSEX mem_status;
|
||||
|
@ -456,7 +581,7 @@ Error systemErrorCodeToError() {
|
|||
void getDiskBytes(std::string const& directory, int64_t& free, int64_t& total) {
|
||||
INJECT_FAULT( platform_error, "getDiskBytes" );
|
||||
#if defined(__unixish__)
|
||||
#ifdef __linux__
|
||||
#if defined (__linux__) || defined (__FreeBSD__)
|
||||
struct statvfs buf;
|
||||
if (statvfs(directory.c_str(), &buf)) {
|
||||
Error e = systemErrorCodeToError();
|
||||
|
@ -755,6 +880,196 @@ dev_t getDeviceId(std::string path) {
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
void getNetworkTraffic(const IPAddress ip, uint64_t& bytesSent, uint64_t& bytesReceived,
|
||||
uint64_t& outSegs, uint64_t& retransSegs) {
|
||||
INJECT_FAULT( platform_error, "getNetworkTraffic" );
|
||||
|
||||
const char* ifa_name = nullptr;
|
||||
try {
|
||||
ifa_name = getInterfaceName(ip);
|
||||
}
|
||||
catch(Error &e) {
|
||||
if(e.code() != error_code_platform_error) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ifa_name)
|
||||
return;
|
||||
|
||||
struct ifaddrs *interfaces = NULL;
|
||||
|
||||
if (getifaddrs(&interfaces))
|
||||
{
|
||||
TraceEvent(SevError, "GetNetworkTrafficError").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
int if_count, i;
|
||||
int mib[6];
|
||||
size_t ifmiblen;
|
||||
struct ifmibdata ifmd;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_LINK;
|
||||
mib[2] = NETLINK_GENERIC;
|
||||
mib[3] = IFMIB_IFDATA;
|
||||
mib[4] = IFMIB_IFCOUNT;
|
||||
mib[5] = IFDATA_GENERAL;
|
||||
|
||||
ifmiblen = sizeof(ifmd);
|
||||
|
||||
for (i = 1; i <= if_count; i++)
|
||||
{
|
||||
mib[4] = i;
|
||||
|
||||
sysctl(mib, 6, &ifmd, &ifmiblen, (void *)0, 0);
|
||||
|
||||
if (!strcmp(ifmd.ifmd_name, ifa_name))
|
||||
{
|
||||
bytesSent = ifmd.ifmd_data.ifi_obytes;
|
||||
bytesReceived = ifmd.ifmd_data.ifi_ibytes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(interfaces);
|
||||
|
||||
struct tcpstat tcpstat;
|
||||
size_t stat_len;
|
||||
stat_len = sizeof(tcpstat);
|
||||
int tcpstatus = sysctlbyname("net.inet.tcp.stats", &tcpstat, &stat_len, NULL, 0);
|
||||
if (tcpstatus < 0) {
|
||||
TraceEvent(SevError, "GetNetworkTrafficError").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
outSegs = tcpstat.tcps_sndtotal;
|
||||
retransSegs = tcpstat.tcps_sndrexmitpack;
|
||||
}
|
||||
|
||||
void getMachineLoad(uint64_t& idleTime, uint64_t& totalTime, bool logDetails) {
|
||||
INJECT_FAULT( platform_error, "getMachineLoad" );
|
||||
|
||||
long cur[CPUSTATES], last[CPUSTATES];
|
||||
size_t cur_sz = sizeof cur;
|
||||
int cpustate;
|
||||
long sum;
|
||||
|
||||
memset(last, 0, sizeof last);
|
||||
|
||||
if (sysctlbyname("kern.cp_time", &cur, &cur_sz, NULL, 0) < 0)
|
||||
{
|
||||
TraceEvent(SevError, "GetMachineLoad").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
sum = 0;
|
||||
for (cpustate = 0; cpustate < CPUSTATES; cpustate++)
|
||||
{
|
||||
long tmp = cur[cpustate];
|
||||
cur[cpustate] -= last[cpustate];
|
||||
last[cpustate] = tmp;
|
||||
sum += cur[cpustate];
|
||||
}
|
||||
|
||||
totalTime = (uint64_t)(cur[CP_USER] + cur[CP_NICE] + cur[CP_SYS] + cur[CP_IDLE]);
|
||||
|
||||
idleTime = (uint64_t)(cur[CP_IDLE]);
|
||||
|
||||
//need to add logging here to TraceEvent
|
||||
|
||||
}
|
||||
|
||||
void getDiskStatistics(std::string const& directory, uint64_t& currentIOs, uint64_t& busyTicks, uint64_t& reads, uint64_t& writes, uint64_t& writeSectors, uint64_t& readSectors) {
|
||||
INJECT_FAULT( platform_error, "getDiskStatistics" );
|
||||
currentIOs = 0;
|
||||
busyTicks = 0;
|
||||
reads = 0;
|
||||
writes = 0;
|
||||
writeSectors = 0;
|
||||
readSectors = 0;
|
||||
|
||||
struct stat buf;
|
||||
if (stat(directory.c_str(), &buf)) {
|
||||
TraceEvent(SevError, "GetDiskStatisticsStatError").detail("Directory", directory).GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
static struct statinfo dscur;
|
||||
double etime;
|
||||
struct timespec ts;
|
||||
static int num_devices;
|
||||
|
||||
kvm_t *kd = NULL;
|
||||
|
||||
etime = ts.tv_nsec * 1e-6;;
|
||||
|
||||
int dn;
|
||||
u_int64_t total_transfers_read, total_transfers_write;
|
||||
u_int64_t total_blocks_read, total_blocks_write;
|
||||
u_int64_t queue_len;
|
||||
long double ms_per_transaction;
|
||||
|
||||
dscur.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo));
|
||||
if (dscur.dinfo == NULL) {
|
||||
TraceEvent(SevError, "GetDiskStatisticsStatError").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
if (devstat_getdevs(kd, &dscur) == -1) {
|
||||
TraceEvent(SevError, "GetDiskStatisticsStatError").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
num_devices = dscur.dinfo->numdevs;
|
||||
|
||||
for (dn = 0; dn < num_devices; dn++)
|
||||
{
|
||||
|
||||
if (devstat_compute_statistics(&dscur.dinfo->devices[dn], NULL, etime,
|
||||
DSM_MS_PER_TRANSACTION, &ms_per_transaction,
|
||||
DSM_TOTAL_TRANSFERS_READ, &total_transfers_read,
|
||||
DSM_TOTAL_TRANSFERS_WRITE, &total_transfers_write,
|
||||
DSM_TOTAL_BLOCKS_READ, &total_blocks_read,
|
||||
DSM_TOTAL_BLOCKS_WRITE, &total_blocks_write,
|
||||
DSM_QUEUE_LENGTH, &queue_len,
|
||||
DSM_NONE) != 0) {
|
||||
TraceEvent(SevError, "GetDiskStatisticsStatError").GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
|
||||
currentIOs = queue_len;
|
||||
busyTicks = (u_int64_t)ms_per_transaction;
|
||||
reads = total_transfers_read;
|
||||
writes = total_transfers_write;
|
||||
writeSectors = total_blocks_read;
|
||||
readSectors = total_blocks_write;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dev_t getDeviceId(std::string path) {
|
||||
struct stat statInfo;
|
||||
|
||||
while (true) {
|
||||
int returnValue = stat(path.c_str(), &statInfo);
|
||||
if (!returnValue) break;
|
||||
|
||||
if (errno == ENOENT) {
|
||||
path = parentDirectory(path);
|
||||
} else {
|
||||
TraceEvent(SevError, "GetDeviceIdError").detail("Path", path).GetLastError();
|
||||
throw platform_error();
|
||||
}
|
||||
}
|
||||
|
||||
return statInfo.st_dev;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
void getNetworkTraffic(const IPAddress& ip, uint64_t& bytesSent, uint64_t& bytesReceived, uint64_t& outSegs,
|
||||
uint64_t& retransSegs) {
|
||||
|
@ -1277,7 +1592,7 @@ struct OffsetTimer {
|
|||
return offset + count * secondsPerCount;
|
||||
}
|
||||
};
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
#define DOUBLETIME(ts) (double(ts.tv_sec) + (ts.tv_nsec * 1e-9))
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW 4 // Confirmed safe to do with glibc >= 2.11 and kernel >= 2.6.28. No promises with older glibc. Older kernel definitely breaks it.
|
||||
|
@ -1342,7 +1657,7 @@ double timer() {
|
|||
GetSystemTimeAsFileTime(&fileTime);
|
||||
static_assert( sizeof(fileTime) == sizeof(uint64_t), "FILETIME size wrong" );
|
||||
return (*(uint64_t*)&fileTime - FILETIME_C_EPOCH) * 100e-9;
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
return double(ts.tv_sec) + (ts.tv_nsec * 1e-9);
|
||||
|
@ -1362,7 +1677,7 @@ uint64_t timer_int() {
|
|||
GetSystemTimeAsFileTime(&fileTime);
|
||||
static_assert( sizeof(fileTime) == sizeof(uint64_t), "FILETIME size wrong" );
|
||||
return (*(uint64_t*)&fileTime - FILETIME_C_EPOCH);
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
return uint64_t(ts.tv_sec) * 1e9 + ts.tv_nsec;
|
||||
|
@ -1412,7 +1727,7 @@ void setMemoryQuota( size_t limit ) {
|
|||
}
|
||||
if (!AssignProcessToJobObject( job, GetCurrentProcess() ))
|
||||
TraceEvent(SevWarn, "FailedToSetMemoryLimit").GetLastError();
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
struct rlimit rlim;
|
||||
if (getrlimit(RLIMIT_AS, &rlim)) {
|
||||
TraceEvent(SevError, "GetMemoryLimit").GetLastError();
|
||||
|
@ -1514,7 +1829,7 @@ static void *allocateInternal(size_t length, bool largePages) {
|
|||
flags |= MAP_HUGETLB;
|
||||
|
||||
return mmap(NULL, length, PROT_READ|PROT_WRITE, flags, -1, 0);
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
int flags = MAP_PRIVATE|MAP_ANON;
|
||||
|
||||
return mmap(NULL, length, PROT_READ|PROT_WRITE, flags, -1, 0);
|
||||
|
@ -1588,6 +1903,11 @@ void setAffinity(int proc) {
|
|||
CPU_ZERO(&set);
|
||||
CPU_SET(proc, &set);
|
||||
sched_setaffinity(0, sizeof(cpu_set_t), &set);
|
||||
#elif defined(__FreeBSD__)
|
||||
cpuset_t set;
|
||||
CPU_ZERO(&set);
|
||||
CPU_SET(proc, &set);
|
||||
cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,sizeof(set), &set);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1648,7 +1968,7 @@ void renameFile( std::string const& fromPath, std::string const& toPath ) {
|
|||
//renamedFile();
|
||||
return;
|
||||
}
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
if (!rename( fromPath.c_str(), toPath.c_str() )) {
|
||||
//FIXME: We cannot inject faults after renaming the file, because we could end up with two asyncFileNonDurable open for the same file
|
||||
//renamedFile();
|
||||
|
@ -1814,7 +2134,7 @@ bool createDirectory( std::string const& directory ) {
|
|||
Error e = systemErrorCodeToError();
|
||||
TraceEvent(SevError, "CreateDirectory").detail("Directory", directory).GetLastError().error(e);
|
||||
throw e;
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
size_t sep = 0;
|
||||
do {
|
||||
sep = directory.find_first_of('/', sep + 1);
|
||||
|
@ -1967,8 +2287,7 @@ std::string abspath( std::string const& path, bool resolveLinks, bool mustExist
|
|||
if (*x == '/')
|
||||
*x = CANONICAL_PATH_SEPARATOR;
|
||||
return nameBuffer;
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
char result[PATH_MAX];
|
||||
// Must resolve links, so first try realpath on the whole thing
|
||||
const char *r = realpath( path.c_str(), result );
|
||||
|
@ -2031,7 +2350,7 @@ std::string getUserHomeDirectory() {
|
|||
|
||||
#ifdef _WIN32
|
||||
#define FILE_ATTRIBUTE_DATA DWORD
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
#define FILE_ATTRIBUTE_DATA mode_t
|
||||
#else
|
||||
#error Port me!
|
||||
|
@ -2040,7 +2359,7 @@ std::string getUserHomeDirectory() {
|
|||
bool acceptFile( FILE_ATTRIBUTE_DATA fileAttributes, std::string name, std::string extension ) {
|
||||
#ifdef _WIN32
|
||||
return !(fileAttributes & FILE_ATTRIBUTE_DIRECTORY) && StringRef(name).endsWith(extension);
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
return S_ISREG(fileAttributes) && StringRef(name).endsWith(extension);
|
||||
#else
|
||||
#error Port me!
|
||||
|
@ -2050,7 +2369,7 @@ bool acceptFile( FILE_ATTRIBUTE_DATA fileAttributes, std::string name, std::stri
|
|||
bool acceptDirectory( FILE_ATTRIBUTE_DATA fileAttributes, std::string name, std::string extension ) {
|
||||
#ifdef _WIN32
|
||||
return (fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
return S_ISDIR(fileAttributes);
|
||||
#else
|
||||
#error Port me!
|
||||
|
@ -2086,7 +2405,7 @@ std::vector<std::string> findFiles( std::string const& directory, std::string co
|
|||
}
|
||||
FindClose(h);
|
||||
}
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
DIR *dip;
|
||||
|
||||
if ((dip = opendir(directory.c_str())) != NULL) {
|
||||
|
@ -2150,7 +2469,7 @@ void findFilesRecursively(std::string path, std::vector<std::string> &out) {
|
|||
void threadSleep( double seconds ) {
|
||||
#ifdef _WIN32
|
||||
Sleep( (DWORD)(seconds * 1e3) );
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
struct timespec req, rem;
|
||||
|
||||
req.tv_sec = seconds;
|
||||
|
@ -2201,7 +2520,7 @@ void setCloseOnExec( int fd ) {
|
|||
THREAD_HANDLE startThread(void (*func) (void *), void *arg) {
|
||||
return (void *)_beginthread(func, 0, arg);
|
||||
}
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
THREAD_HANDLE startThread(void *(*func) (void *), void *arg) {
|
||||
pthread_t t;
|
||||
pthread_create(&t, NULL, func, arg);
|
||||
|
@ -2214,7 +2533,7 @@ THREAD_HANDLE startThread(void *(*func) (void *), void *arg) {
|
|||
void waitThread(THREAD_HANDLE thread) {
|
||||
#ifdef _WIN32
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
pthread_join(thread, NULL);
|
||||
#else
|
||||
#error Port me!
|
||||
|
@ -2256,7 +2575,7 @@ int64_t fileSize(std::string const& filename) {
|
|||
return 0;
|
||||
else
|
||||
return file_status.st_size;
|
||||
#elif (defined(__linux__) || defined(__APPLE__))
|
||||
#elif (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
struct stat file_status;
|
||||
if(stat(filename.c_str(), &file_status) != 0)
|
||||
return 0;
|
||||
|
@ -2395,7 +2714,7 @@ std::string getDefaultConfigPath() {
|
|||
return _filepath + "\\foundationdb";
|
||||
#elif defined(__linux__)
|
||||
return "/etc/foundationdb";
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
return "/usr/local/etc/foundationdb";
|
||||
#else
|
||||
#error Port me!
|
||||
|
@ -2524,7 +2843,7 @@ int eraseDirectoryRecursive(std::string const& dir) {
|
|||
__eraseDirectoryRecurseiveCount = 0;
|
||||
#ifdef _WIN32
|
||||
system( ("rd /s /q \"" + dir + "\"").c_str() );
|
||||
#elif defined(__linux__) || defined(__APPLE__)
|
||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
|
||||
int error =
|
||||
nftw(dir.c_str(),
|
||||
[](const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) -> int {
|
||||
|
@ -2701,7 +3020,7 @@ void* getImageOffset() { return NULL; }
|
|||
#endif
|
||||
|
||||
bool isLibraryLoaded(const char* lib_path) {
|
||||
#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32)
|
||||
#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__FreeBSD__)
|
||||
#error Port me!
|
||||
#endif
|
||||
|
||||
|
@ -2717,7 +3036,7 @@ bool isLibraryLoaded(const char* lib_path) {
|
|||
}
|
||||
|
||||
void* loadLibrary(const char* lib_path) {
|
||||
#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32)
|
||||
#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__FreeBSD__)
|
||||
#error Port me!
|
||||
#endif
|
||||
|
||||
|
@ -2774,6 +3093,20 @@ std::string exePath() {
|
|||
} else {
|
||||
throw platform_error();
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
char binPath[2048];
|
||||
int mib[4];
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PATHNAME;
|
||||
mib[3] = -1;
|
||||
size_t len = sizeof(binPath);
|
||||
if (sysctl(mib, 4, binPath, &len, NULL, 0) != 0) {
|
||||
binPath[0] = '\0';
|
||||
return std::string(binPath);
|
||||
} else {
|
||||
throw platform_error();
|
||||
}
|
||||
#elif defined(__APPLE__)
|
||||
uint32_t bufSize = 1024;
|
||||
std::unique_ptr<char[]> buf(new char[bufSize]);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#define FLOW_PLATFORM_H
|
||||
#pragma once
|
||||
|
||||
#if (defined(__linux__) || defined(__APPLE__))
|
||||
#if (defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__))
|
||||
#define __unixish__ 1
|
||||
#endif
|
||||
|
||||
|
@ -172,6 +172,8 @@ THREAD_HANDLE startThread(void *(func) (void *), void *arg);
|
|||
#define DYNAMIC_LIB_EXT ".dll"
|
||||
#elif defined(__linux)
|
||||
#define DYNAMIC_LIB_EXT ".so"
|
||||
#elif defined(__FreeBSD__)
|
||||
#define DYNAMIC_LIB_EXT ".so"
|
||||
#elif defined(__APPLE__)
|
||||
#define DYNAMIC_LIB_EXT ".dylib"
|
||||
#else
|
||||
|
@ -422,6 +424,16 @@ inline static uint64_t __rdtsc() {
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#if !(__has_builtin(__rdtsc))
|
||||
inline static uint64_t __rdtsc() {
|
||||
uint64_t lo, hi;
|
||||
asm( "rdtsc" : "=a" (lo), "=d" (hi) );
|
||||
return( lo | (hi << 32) );
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <intrin.h>
|
||||
inline static int32_t interlockedIncrement(volatile int32_t *a) { return _InterlockedIncrement((long*)a); }
|
||||
|
@ -531,6 +543,8 @@ inline static void aligned_free(void* ptr) { free(ptr); }
|
|||
#if (!defined(_ISOC11_SOURCE)) // old libc versions
|
||||
inline static void* aligned_alloc(size_t alignment, size_t size) { return memalign(alignment, size); }
|
||||
#endif
|
||||
#elif defined(__FreeBSD__)
|
||||
inline static void aligned_free(void* ptr) { free(ptr); }
|
||||
#elif defined(__APPLE__)
|
||||
#if !defined(HAS_ALIGNED_ALLOC)
|
||||
#include <cstdlib>
|
||||
|
|
|
@ -37,7 +37,7 @@ extern std::string format( const char *form, ... );
|
|||
Event::Event() {
|
||||
#ifdef _WIN32
|
||||
ev = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
int result = sem_init(&sem, 0, 0);
|
||||
if (result)
|
||||
criticalError(FDB_EXIT_INIT_SEMAPHORE, "UnableToInitializeSemaphore", format("Could not initialize semaphore - %s", strerror(errno)).c_str());
|
||||
|
@ -54,7 +54,7 @@ Event::Event() {
|
|||
Event::~Event() {
|
||||
#ifdef _WIN32
|
||||
CloseHandle(ev);
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
sem_destroy(&sem);
|
||||
#elif defined(__APPLE__)
|
||||
semaphore_destroy(self, sem);
|
||||
|
@ -66,7 +66,7 @@ Event::~Event() {
|
|||
void Event::set() {
|
||||
#ifdef _WIN32
|
||||
SetEvent(ev);
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
sem_post(&sem);
|
||||
#elif defined(__APPLE__)
|
||||
semaphore_signal(sem);
|
||||
|
@ -78,7 +78,7 @@ void Event::set() {
|
|||
void Event::block() {
|
||||
#ifdef _WIN32
|
||||
WaitForSingleObject(ev, INFINITE);
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
int ret;
|
||||
do {
|
||||
ret = sem_wait(&sem);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "flow/Error.h"
|
||||
#include "flow/Trace.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
|
||||
|
@ -115,7 +115,7 @@ public:
|
|||
private:
|
||||
#ifdef _WIN32
|
||||
void* ev;
|
||||
#elif defined(__linux__)
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
sem_t sem;
|
||||
#elif defined(__APPLE__)
|
||||
mach_port_t self;
|
||||
|
|
Loading…
Reference in New Issue