Commit c79c45d6 authored by Dominik Charousset's avatar Dominik Charousset

support Boost >= 1.54 only and use Boost.Lockfree

this patch adds the config option "--standalone-build" that disables
Boost integration (by defining `CPPA_STANDALONE_BUILD`) and uses
the Boost.Lockfree queue as job list if compiled with Boost support
parent 246fd7e3
......@@ -255,44 +255,33 @@ if (DISABLE_MEM_MANAGEMENT)
add_definitions(-DCPPA_DISABLE_MEM_MANAGEMENT)
endif (DISABLE_MEM_MANAGEMENT)
if (DISABLE_CONTEXT_SWITCHING)
# explicitly disabled
else (DISABLE_CONTEXT_SWITCHING)
find_package(Boost 1.51.0 COMPONENTS context)
if (STANDALONE_BUILD)
add_definitions(-DCPPA_STANDALONE_BUILD)
endif (STANDALONE_BUILD)
if (STANDALONE_BUILD)
# explicitly disabled, don't include Boost
else (STANDALONE_BUILD)
find_package(Boost 1.54.0 COMPONENTS system context coroutine)
# without REQUIRED, find_package(Boost...) returns with Boost_FOUND=FALSE
if (NOT Boost_FOUND)
# disable implicitly
add_definitions(-DCPPA_STANDALONE_BUILD)
set(DISABLE_CONTEXT_SWITCHING true)
else (NOT Boost_FOUND)
if (${Boost_VERSION} LESS 105400)
set(LD_FLAGS ${LD_FLAGS} ${Boost_CONTEXT_LIBRARY})
# nothing to do in this case
else ()
# for boost >= 1.54, we need coroutines as well
message(STATUS "Detected Boost >= 1.54.0, check for coroutines & system")
find_package(Boost 1.51.0 COMPONENTS system context coroutine)
if (Boost_FOUND)
set(LD_FLAGS ${LD_FLAGS} ${Boost_COROUTINE_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY})
endif ()
endif ()
# check again, as second find_package might set this to false
if (Boost_FOUND)
# This hack fixes a problem when the linker search path is the same as
# the one provided by the compiler. In this case, CMake replaces the absolute
# path (e.g., /path/to/lib.so) with -l<lib>, which may cause it to pick up the wrong
# library. So when this replacement happens, we ensure that the right
# library gets picked by adding a -L directive for the affected libraries
# (which is just Boost Context here).
set(CMAKE_EXE_LINKER_FLAGS -L${Boost_LIBRARY_DIRS})
set(INCLUDE_DIRS ${INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
set(LD_DIRS ${LD_DIRS} ${Boost_LIBRARY_DIRS})
set(DISABLE_CONTEXT_SWITCHING false)
else ()
# disable implicitly
set(DISABLE_CONTEXT_SWITCHING true)
endif ()
set(LD_FLAGS ${LD_FLAGS} ${Boost_COROUTINE_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY})
# This hack fixes a problem when the linker search path is the same as
# the one provided by the compiler. In this case, CMake replaces the absolute
# path (e.g., /path/to/lib.so) with -l<lib>, which may cause it to pick up the wrong
# library. So when this replacement happens, we ensure that the right
# library gets picked by adding a -L directive for the affected libraries
# (which is just Boost Context here).
set(CMAKE_EXE_LINKER_FLAGS -L${Boost_LIBRARY_DIRS})
set(INCLUDE_DIRS ${INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
set(LD_DIRS ${LD_DIRS} ${Boost_LIBRARY_DIRS})
set(DISABLE_CONTEXT_SWITCHING false)
endif (NOT Boost_FOUND)
endif (DISABLE_CONTEXT_SWITCHING)
endif (STANDALONE_BUILD)
# set compiler flag when compiling w/o context-switching actors
if (DISABLE_CONTEXT_SWITCHING)
......
......@@ -37,6 +37,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--build-static-only build libcppa as static library only
--with-opencl build libcppa with OpenCL support
--without-memory-management build libcppa without memory management
--standalone-build build libcppa without Boost or other dependencies
Installation Directories:
--prefix=PREFIX installation directory [/usr/local]
......@@ -187,6 +188,9 @@ while [ $# -ne 0 ]; do
--without-memory-management)
append_cache_entry DISABLE_MEM_MANAGEMENT BOOL true
;;
--standalone-build)
append_cache_entry STANDALONE_BUILD BOOL true
;;
--with-cppa-log-level=*)
level=$(echo "$optarg" | tr '[:lower:]' '[:upper:]')
case $level in
......
......@@ -31,6 +31,24 @@
#ifndef CPPA_CONFIG_HPP
#define CPPA_CONFIG_HPP
// Config pararameters defined by the build system (usually CMake):
//
// CPPA_STANDALONE_BUILD:
// - builds libcppa without Boost
//
// CPPA_DISABLE_CONTEXT_SWITCHING:
// - disables context switching even if Boost is available
//
// CPPA_DEBUG_MODE:
// - check requirements at runtime
//
// CPPA_LOG_LEVEL:
// - denotes the amount of logging, ranging from error messages only (0)
// to complete traces (4)
//
// CPPA_OPENCL:
// - enables optional OpenCL module
/**
* @brief Denotes the libcppa version in the format {MAJOR}{MINOR}{PATCH},
* whereas each number is a two-digit decimal number without
......@@ -56,6 +74,7 @@
_Pragma("clang diagnostic ignored \"-Wextra-semi\"") \
_Pragma("clang diagnostic ignored \"-Wdocumentation\"") \
_Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \
_Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
_Pragma("clang diagnostic ignored \"-Wundef\"")
# define CPPA_POP_WARNINGS \
_Pragma("clang diagnostic pop")
......@@ -93,7 +112,7 @@
#elif defined(WIN32)
# define CPPA_WINDOWS
#else
# error Plattform and/or compiler not supportet
# error Platform and/or compiler not supportet
#endif
#include <memory>
......
......@@ -31,6 +31,46 @@
#ifndef CPPA_PRODUCER_CONSUMER_LIST_HPP
#define CPPA_PRODUCER_CONSUMER_LIST_HPP
#include "cppa/config.hpp"
#ifndef CPPA_STANDALONE_BUILD
CPPA_PUSH_WARNINGS
#include <boost/lockfree/queue.hpp>
CPPA_POP_WARNINGS
namespace cppa {
namespace util {
template<typename T>
class producer_consumer_list {
public:
inline T* try_pop() {
T* res;
return m_queue.pop(res) ? res : nullptr;
}
inline void push_back(T* ptr) {
m_queue.push(ptr);
}
inline bool empty() {
return m_queue.empty();
}
private:
boost::lockfree::queue<T*> m_queue;
};
} // namespace util
} // namespace cppa
#else // fallback implementation in case Boost is not available
#define CPPA_CACHE_LINE_SIZE 64
#include <chrono>
......@@ -199,4 +239,6 @@ class producer_consumer_list {
} } // namespace cppa::util
#endif // CPPA_STANDALONE_BUILD
#endif // CPPA_PRODUCER_CONSUMER_LIST_HPP
......@@ -51,7 +51,7 @@ constexpr size_t stack_multiplier = 2;
} // namespace <anonmyous>
#ifdef CPPA_DISABLE_CONTEXT_SWITCHING
#if defined(CPPA_DISABLE_CONTEXT_SWITCHING) || defined(CPPA_STANDALONE_BUILD)
namespace cppa { namespace detail {
......@@ -70,7 +70,7 @@ const bool cs_thread::is_disabled_feature = true;
} } // namespace cppa::detail
#else // ifdef CPPA_DISABLE_CONTEXT_SWITCHING
#else // CPPA_DISABLE_CONTEXT_SWITCHING || CPPA_STANDALONE_BUILD
// optional valgrind include
#ifdef CPPA_ANNOTATE_VALGRIND
......@@ -81,9 +81,7 @@ CPPA_PUSH_WARNINGS
// boost includes
#include <boost/version.hpp>
#include <boost/context/all.hpp>
#if BOOST_VERSION >= 105300
# include <boost/coroutine/all.hpp>
#endif
#include <boost/coroutine/all.hpp>
CPPA_POP_WARNINGS
namespace cppa { namespace detail {
......@@ -142,72 +140,7 @@ namespace {
* void del_stack(stack_allocator&, ctx_stack_info, vg_member&):
* destroys the stack and (optionally) deregisters it from valgrind
*/
#if BOOST_VERSION == 105100
// === namespace aliases ===
namespace ctxn = boost::ctx;
// === types ===
typedef ctxn::fcontext_t context;
struct converted_context { };
typedef int ctx_stack_info;
typedef ctxn::stack_allocator stack_allocator;
// === functions ===
inline void init_converted_context(converted_context&, context&) {/*NOP*/}
inline void ctx_switch(context& from, context& to, cst_impl* ptr) {
ctxn::jump_fcontext(&from, &to, (intptr_t) ptr);
}
ctx_stack_info new_stack(context& ctx,
stack_allocator& alloc,
vg_member& vgm) {
auto mss = static_cast<intptr_t>( ctxn::minimum_stacksize()
* stack_multiplier);
ctx.fc_stack.base = alloc.allocate(mss);
ctx.fc_stack.limit = reinterpret_cast<vptr>(
reinterpret_cast<intptr_t>(ctx.fc_stack.base) - mss);
ctxn::make_fcontext(&ctx, cst_trampoline);
vg_register(vgm,
ctx.fc_stack.base,
reinterpret_cast<vptr>(
reinterpret_cast<intptr_t>(ctx.fc_stack.base) - mss));
return 0; // dummy value
}
inline void del_stack(stack_allocator&, ctx_stack_info, vg_member& vgm) {
vg_deregister(vgm);
}
#elif BOOST_VERSION < 105400
// === namespace aliases ===
namespace ctxn = boost::context;
// === types ===
typedef ctxn::fcontext_t* context;
typedef ctxn::fcontext_t converted_context;
typedef int ctx_stack_info;
# if BOOST_VERSION < 105300
typedef ctxn::guarded_stack_allocator stack_allocator;
# else
typedef boost::coroutines::stack_allocator stack_allocator;
# endif
// === functions ===
inline void init_converted_context(converted_context& cctx, context& ctx) {
ctx = &cctx;
}
inline void ctx_switch(context& from, context& to, cst_impl* ptr) {
ctxn::jump_fcontext(from, to, (intptr_t) ptr);
}
ctx_stack_info new_stack(context& ctx,
stack_allocator& alloc,
vg_member& vgm) {
auto mss = static_cast<intptr_t>( stack_allocator::minimum_stacksize()
* stack_multiplier);
ctx = ctxn::make_fcontext(alloc.allocate(mss), mss, cst_trampoline);
vg_register(vgm,
ctx->fc_stack.sp,
reinterpret_cast<vptr>(
reinterpret_cast<intptr_t>(ctx->fc_stack.sp) - mss));
return 0; // dummy value
}
inline void del_stack(stack_allocator&, ctx_stack_info, vg_member& vgm) {
vg_deregister(vgm);
}
#else // BOOST_VERSION >= 105400
#if BOOST_VERSION >= 105400
// === namespace aliases ===
namespace ctxn = boost::context;
// === types ===
......@@ -242,6 +175,8 @@ namespace {
vg_deregister(vgm);
alloc.deallocate(sctx);
}
#else
# error libcppa context switching requires Boost in version >= 1.54
#endif
} // namespace <anonymous>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment