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) ...@@ -255,44 +255,33 @@ if (DISABLE_MEM_MANAGEMENT)
add_definitions(-DCPPA_DISABLE_MEM_MANAGEMENT) add_definitions(-DCPPA_DISABLE_MEM_MANAGEMENT)
endif (DISABLE_MEM_MANAGEMENT) endif (DISABLE_MEM_MANAGEMENT)
if (DISABLE_CONTEXT_SWITCHING) if (STANDALONE_BUILD)
# explicitly disabled add_definitions(-DCPPA_STANDALONE_BUILD)
else (DISABLE_CONTEXT_SWITCHING) endif (STANDALONE_BUILD)
find_package(Boost 1.51.0 COMPONENTS context)
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 # without REQUIRED, find_package(Boost...) returns with Boost_FOUND=FALSE
if (NOT Boost_FOUND) if (NOT Boost_FOUND)
# disable implicitly # disable implicitly
add_definitions(-DCPPA_STANDALONE_BUILD)
set(DISABLE_CONTEXT_SWITCHING true) set(DISABLE_CONTEXT_SWITCHING true)
else (NOT Boost_FOUND) else (NOT Boost_FOUND)
if (${Boost_VERSION} LESS 105400) set(LD_FLAGS ${LD_FLAGS} ${Boost_COROUTINE_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY})
set(LD_FLAGS ${LD_FLAGS} ${Boost_CONTEXT_LIBRARY}) # This hack fixes a problem when the linker search path is the same as
# nothing to do in this case # the one provided by the compiler. In this case, CMake replaces the absolute
else () # path (e.g., /path/to/lib.so) with -l<lib>, which may cause it to pick up the wrong
# for boost >= 1.54, we need coroutines as well # library. So when this replacement happens, we ensure that the right
message(STATUS "Detected Boost >= 1.54.0, check for coroutines & system") # library gets picked by adding a -L directive for the affected libraries
find_package(Boost 1.51.0 COMPONENTS system context coroutine) # (which is just Boost Context here).
if (Boost_FOUND) set(CMAKE_EXE_LINKER_FLAGS -L${Boost_LIBRARY_DIRS})
set(LD_FLAGS ${LD_FLAGS} ${Boost_COROUTINE_LIBRARY} ${Boost_CONTEXT_LIBRARY} ${Boost_SYSTEM_LIBRARY}) set(INCLUDE_DIRS ${INCLUDE_DIRS} ${Boost_INCLUDE_DIRS})
endif () set(LD_DIRS ${LD_DIRS} ${Boost_LIBRARY_DIRS})
endif () set(DISABLE_CONTEXT_SWITCHING false)
# 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 ()
endif (NOT Boost_FOUND) endif (NOT Boost_FOUND)
endif (DISABLE_CONTEXT_SWITCHING) endif (STANDALONE_BUILD)
# set compiler flag when compiling w/o context-switching actors # set compiler flag when compiling w/o context-switching actors
if (DISABLE_CONTEXT_SWITCHING) if (DISABLE_CONTEXT_SWITCHING)
......
...@@ -37,6 +37,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]... ...@@ -37,6 +37,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--build-static-only build libcppa as static library only --build-static-only build libcppa as static library only
--with-opencl build libcppa with OpenCL support --with-opencl build libcppa with OpenCL support
--without-memory-management build libcppa without memory management --without-memory-management build libcppa without memory management
--standalone-build build libcppa without Boost or other dependencies
Installation Directories: Installation Directories:
--prefix=PREFIX installation directory [/usr/local] --prefix=PREFIX installation directory [/usr/local]
...@@ -187,6 +188,9 @@ while [ $# -ne 0 ]; do ...@@ -187,6 +188,9 @@ while [ $# -ne 0 ]; do
--without-memory-management) --without-memory-management)
append_cache_entry DISABLE_MEM_MANAGEMENT BOOL true append_cache_entry DISABLE_MEM_MANAGEMENT BOOL true
;; ;;
--standalone-build)
append_cache_entry STANDALONE_BUILD BOOL true
;;
--with-cppa-log-level=*) --with-cppa-log-level=*)
level=$(echo "$optarg" | tr '[:lower:]' '[:upper:]') level=$(echo "$optarg" | tr '[:lower:]' '[:upper:]')
case $level in case $level in
......
...@@ -31,6 +31,24 @@ ...@@ -31,6 +31,24 @@
#ifndef CPPA_CONFIG_HPP #ifndef CPPA_CONFIG_HPP
#define 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}, * @brief Denotes the libcppa version in the format {MAJOR}{MINOR}{PATCH},
* whereas each number is a two-digit decimal number without * whereas each number is a two-digit decimal number without
...@@ -56,6 +74,7 @@ ...@@ -56,6 +74,7 @@
_Pragma("clang diagnostic ignored \"-Wextra-semi\"") \ _Pragma("clang diagnostic ignored \"-Wextra-semi\"") \
_Pragma("clang diagnostic ignored \"-Wdocumentation\"") \ _Pragma("clang diagnostic ignored \"-Wdocumentation\"") \
_Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \ _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \
_Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
_Pragma("clang diagnostic ignored \"-Wundef\"") _Pragma("clang diagnostic ignored \"-Wundef\"")
# define CPPA_POP_WARNINGS \ # define CPPA_POP_WARNINGS \
_Pragma("clang diagnostic pop") _Pragma("clang diagnostic pop")
...@@ -93,7 +112,7 @@ ...@@ -93,7 +112,7 @@
#elif defined(WIN32) #elif defined(WIN32)
# define CPPA_WINDOWS # define CPPA_WINDOWS
#else #else
# error Plattform and/or compiler not supportet # error Platform and/or compiler not supportet
#endif #endif
#include <memory> #include <memory>
......
...@@ -31,6 +31,46 @@ ...@@ -31,6 +31,46 @@
#ifndef CPPA_PRODUCER_CONSUMER_LIST_HPP #ifndef CPPA_PRODUCER_CONSUMER_LIST_HPP
#define 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 #define CPPA_CACHE_LINE_SIZE 64
#include <chrono> #include <chrono>
...@@ -199,4 +239,6 @@ class producer_consumer_list { ...@@ -199,4 +239,6 @@ class producer_consumer_list {
} } // namespace cppa::util } } // namespace cppa::util
#endif // CPPA_STANDALONE_BUILD
#endif // CPPA_PRODUCER_CONSUMER_LIST_HPP #endif // CPPA_PRODUCER_CONSUMER_LIST_HPP
...@@ -51,7 +51,7 @@ constexpr size_t stack_multiplier = 2; ...@@ -51,7 +51,7 @@ constexpr size_t stack_multiplier = 2;
} // namespace <anonmyous> } // namespace <anonmyous>
#ifdef CPPA_DISABLE_CONTEXT_SWITCHING #if defined(CPPA_DISABLE_CONTEXT_SWITCHING) || defined(CPPA_STANDALONE_BUILD)
namespace cppa { namespace detail { namespace cppa { namespace detail {
...@@ -70,7 +70,7 @@ const bool cs_thread::is_disabled_feature = true; ...@@ -70,7 +70,7 @@ const bool cs_thread::is_disabled_feature = true;
} } // namespace cppa::detail } } // namespace cppa::detail
#else // ifdef CPPA_DISABLE_CONTEXT_SWITCHING #else // CPPA_DISABLE_CONTEXT_SWITCHING || CPPA_STANDALONE_BUILD
// optional valgrind include // optional valgrind include
#ifdef CPPA_ANNOTATE_VALGRIND #ifdef CPPA_ANNOTATE_VALGRIND
...@@ -81,9 +81,7 @@ CPPA_PUSH_WARNINGS ...@@ -81,9 +81,7 @@ CPPA_PUSH_WARNINGS
// boost includes // boost includes
#include <boost/version.hpp> #include <boost/version.hpp>
#include <boost/context/all.hpp> #include <boost/context/all.hpp>
#if BOOST_VERSION >= 105300 #include <boost/coroutine/all.hpp>
# include <boost/coroutine/all.hpp>
#endif
CPPA_POP_WARNINGS CPPA_POP_WARNINGS
namespace cppa { namespace detail { namespace cppa { namespace detail {
...@@ -142,72 +140,7 @@ namespace { ...@@ -142,72 +140,7 @@ namespace {
* void del_stack(stack_allocator&, ctx_stack_info, vg_member&): * void del_stack(stack_allocator&, ctx_stack_info, vg_member&):
* destroys the stack and (optionally) deregisters it from valgrind * destroys the stack and (optionally) deregisters it from valgrind
*/ */
#if BOOST_VERSION == 105100 #if BOOST_VERSION >= 105400
// === 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
// === namespace aliases === // === namespace aliases ===
namespace ctxn = boost::context; namespace ctxn = boost::context;
// === types === // === types ===
...@@ -242,6 +175,8 @@ namespace { ...@@ -242,6 +175,8 @@ namespace {
vg_deregister(vgm); vg_deregister(vgm);
alloc.deallocate(sctx); alloc.deallocate(sctx);
} }
#else
# error libcppa context switching requires Boost in version >= 1.54
#endif #endif
} // namespace <anonymous> } // 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