Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
d45b8c6a
Commit
d45b8c6a
authored
Jul 10, 2012
by
neverlord
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'unstable' of github.com:Neverlord/libcppa into unstable
parents
72454443
f4510014
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
163 additions
and
86 deletions
+163
-86
CMakeLists.txt
CMakeLists.txt
+29
-24
configure
configure
+24
-16
cppa/context_switching_actor.hpp
cppa/context_switching_actor.hpp
+1
-6
cppa/detail/thread_pool_scheduler.hpp
cppa/detail/thread_pool_scheduler.hpp
+0
-14
cppa/util/fiber.hpp
cppa/util/fiber.hpp
+0
-16
src/fiber.cpp
src/fiber.cpp
+18
-4
src/thread_pool_scheduler.cpp
src/thread_pool_scheduler.cpp
+34
-6
unit_testing/test__spawn.cpp
unit_testing/test__spawn.cpp
+57
-0
No files found.
CMakeLists.txt
View file @
d45b8c6a
...
@@ -22,6 +22,10 @@ else ()
...
@@ -22,6 +22,10 @@ else ()
set
(
CMAKE_BUILD_TYPE RelWithDebInfo
)
set
(
CMAKE_BUILD_TYPE RelWithDebInfo
)
endif
()
endif
()
if
(
DISABLE_CONTEXT_SWITCHING
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-DCPPA_DISABLE_CONTEXT_SWITCHING"
)
endif
()
if
(
"
${
CMAKE_CXX_COMPILER_ID
}
"
MATCHES
"GNU"
)
if
(
"
${
CMAKE_CXX_COMPILER_ID
}
"
MATCHES
"GNU"
)
execute_process
(
COMMAND
${
CMAKE_CXX_COMPILER
}
-dumpversion
execute_process
(
COMMAND
${
CMAKE_CXX_COMPILER
}
-dumpversion
OUTPUT_VARIABLE GCC_VERSION
)
OUTPUT_VARIABLE GCC_VERSION
)
...
@@ -91,32 +95,33 @@ set(LIBCPPA_SRC
...
@@ -91,32 +95,33 @@ set(LIBCPPA_SRC
set
(
boost_context third_party/boost_context
)
set
(
boost_context third_party/boost_context
)
# add third party Boost.Context sources
# add third party Boost.Context sources if context-switching is enabled
if
(
CMAKE_SIZEOF_VOID_P EQUAL 4
)
if
(
NOT DISABLE_CONTEXT_SWITCHING
)
if
(
APPLE
)
if
(
CMAKE_SIZEOF_VOID_P EQUAL 4
)
set
(
fcontext_asm
${
boost_context
}
/src/asm/fcontext_i386_sysv_macho_gas.S
)
if
(
APPLE
)
else
()
set
(
fcontext_asm
${
boost_context
}
/src/asm/fcontext_i386_sysv_macho_gas.S
)
set
(
fcontext_asm
${
boost_context
}
/src/asm/fcontext_i386_sysv_elf_gas.S
)
else
()
endif
()
set
(
fcontext_asm
${
boost_context
}
/src/asm/fcontext_i386_sysv_elf_gas.S
)
elseif
(
CMAKE_SIZEOF_VOID_P EQUAL 8
)
endif
()
if
(
APPLE
)
elseif
(
CMAKE_SIZEOF_VOID_P EQUAL 8
)
set
(
fcontext_asm
${
boost_context
}
/src/asm/fcontext_x86_64_sysv_macho_gas.S
)
if
(
APPLE
)
set
(
fcontext_asm
${
boost_context
}
/src/asm/fcontext_x86_64_sysv_macho_gas.S
)
else
()
set
(
fcontext_asm
${
boost_context
}
/src/asm/fcontext_x86_64_sysv_elf_gas.S
)
endif
()
else
()
else
()
set
(
fcontext_asm
${
boost_context
}
/src/asm/fcontext_x86_64_sysv_elf_gas.S
)
message
(
FATAL_ERROR
"Unsupported platform (neither 32 nor 64 bit)"
)
endif
()
endif
()
else
()
set_property
(
SOURCE
${
fcontext_asm
}
PROPERTY LANGUAGE CXX
)
message
(
FATAL_ERROR
"Unsupported platform (neither 32 nor 64 bit)"
)
set
(
LIBCPPA_SRC
${
LIBCPPA_SRC
}
${
fcontext_asm
}
${
boost_context
}
/src/stack_utils_posix.cpp
${
boost_context
}
/src/stack_allocator_posix.cpp
${
boost_context
}
/src/fcontext.cpp
)
endif
()
endif
()
set_property
(
SOURCE
${
fcontext_asm
}
PROPERTY LANGUAGE CXX
)
set
(
LIBCPPA_SRC
${
LIBCPPA_SRC
}
${
fcontext_asm
}
${
boost_context
}
/src/stack_utils_posix.cpp
${
boost_context
}
/src/stack_allocator_posix.cpp
${
boost_context
}
/src/fcontext.cpp
)
find_package
(
Boost COMPONENTS thread REQUIRED
)
find_package
(
Boost COMPONENTS thread REQUIRED
)
link_directories
(
${
Boost_LIBRARY_DIRS
}
)
link_directories
(
${
Boost_LIBRARY_DIRS
}
)
...
@@ -127,8 +132,8 @@ add_library(libcppa SHARED ${LIBCPPA_SRC})
...
@@ -127,8 +132,8 @@ add_library(libcppa SHARED ${LIBCPPA_SRC})
target_link_libraries
(
libcppa
${
CMAKE_LD_LIBS
}
${
Boost_THREAD_LIBRARY
}
)
target_link_libraries
(
libcppa
${
CMAKE_LD_LIBS
}
${
Boost_THREAD_LIBRARY
}
)
set
(
LIBCPPA_VERSION_MAJOR 0
)
set
(
LIBCPPA_VERSION_MAJOR 0
)
set
(
LIBCPPA_VERSION_MINOR
2
)
set
(
LIBCPPA_VERSION_MINOR
3
)
set
(
LIBCPPA_VERSION_PATCH
3
)
set
(
LIBCPPA_VERSION_PATCH
0
)
set
(
LIBRARY_VERSION
${
LIBCPPA_VERSION_MAJOR
}
.
${
LIBCPPA_VERSION_MINOR
}
.
${
LIBCPPA_VERSION_PATCH
}
)
set
(
LIBRARY_VERSION
${
LIBCPPA_VERSION_MAJOR
}
.
${
LIBCPPA_VERSION_MINOR
}
.
${
LIBCPPA_VERSION_PATCH
}
)
set
(
LIBRARY_SOVERSION
${
LIBCPPA_VERSION_MAJOR
}
)
set
(
LIBRARY_SOVERSION
${
LIBCPPA_VERSION_MAJOR
}
)
...
...
configure
View file @
d45b8c6a
...
@@ -17,28 +17,32 @@ usage="\
...
@@ -17,28 +17,32 @@ usage="\
Usage:
$0
[OPTION]... [VAR=VALUE]...
Usage:
$0
[OPTION]... [VAR=VALUE]...
Build Options:
Build Options:
--builddir=DIR place build files in directory [build]
--builddir=DIR
place build files in directory [build]
--generator=GENERATOR CMake generator to use (see cmake --help)
--generator=GENERATOR
CMake generator to use (see cmake --help)
--with-clang=FILE path to clang++ executable
--with-clang=FILE
path to clang++ executable
--with-gcc=FILE path to g++ executable
--with-gcc=FILE
path to g++ executable
--bin-dir=DIR executable directory [build/bin]
--bin-dir=DIR
executable directory [build/bin]
--lib-dir=DIR library directory [build/lib]
--lib-dir=DIR
library directory [build/lib]
--dual-build build both with gcc and clang
--dual-build
build both with gcc and clang
Installation Directories:
Installation Directories:
--prefix=PREFIX installation directory [/usr/local]
--prefix=PREFIX
installation directory [/usr/local]
Optional Features:
Optional Features:
--enable-debug compile in debugging mode
--enable-debug compile in debugging mode
--enable-perftools use Google perftools
--enable-perftools use Google perftools
Platform-Dependent Adjustments:
--disable-context-switching compile libcppa without context-switching actors
on platforms where Boost.Context is not available
Required Packages in Non-Standard Locations:
Required Packages in Non-Standard Locations:
--with-boost=PATH path to Boost install root
--with-boost=PATH
path to Boost install root
Influential Environment Variables (only on first invocation
Influential Environment Variables (only on first invocation
per build directory):
per build directory):
CXX C++ compiler command
CXX
C++ compiler command
CXXFLAGS C++ compiler flags
CXXFLAGS
C++ compiler flags
"
"
...
@@ -111,8 +115,9 @@ configure ()
...
@@ -111,8 +115,9 @@ configure ()
# Set defaults.
# Set defaults.
builddir
=
"
$sourcedir
/build"
builddir
=
"
$sourcedir
/build"
CMakeCacheEntries
=
""
CMakeCacheEntries
=
""
append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local
append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local
append_cache_entry ENABLE_DEBUG BOOL
false
append_cache_entry ENABLE_DEBUG BOOL
false
append_cache_entry DISABLE_CONTEXT_SWITCHING BOOL
false
# Parse arguments.
# Parse arguments.
while
[
$#
-ne
0
]
;
do
while
[
$#
-ne
0
]
;
do
...
@@ -138,6 +143,9 @@ while [ $# -ne 0 ]; do
...
@@ -138,6 +143,9 @@ while [ $# -ne 0 ]; do
--enable-debug
)
--enable-debug
)
append_cache_entry ENABLE_DEBUG BOOL
true
append_cache_entry ENABLE_DEBUG BOOL
true
;;
;;
--disable-context-switching
)
append_cache_entry DISABLE_CONTEXT_SWITCHING BOOL
true
;;
--with-boost
=
*
)
--with-boost
=
*
)
append_cache_entry BOOST_ROOT PATH
$optarg
append_cache_entry BOOST_ROOT PATH
$optarg
;;
;;
...
@@ -192,7 +200,7 @@ else
...
@@ -192,7 +200,7 @@ else
configure
$compiler
""
$bindir
$libdir
$CMakeGenerator
configure
$compiler
""
$bindir
$libdir
$CMakeGenerator
fi
fi
printf
"DIRS := %s
\n\n
"
$workdirs
>
$sourcedir
/Makefile
printf
"DIRS := %s
\n\n
"
"
$workdirs
"
>
$sourcedir
/Makefile
makefile
=
$(
cat
<<
'
EOT
'
makefile
=
$(
cat
<<
'
EOT
'
all:
all:
@for i in
$(
DIRS
)
; do
$(
MAKE
)
-C
$$
i
$@
; done
@for i in
$(
DIRS
)
; do
$(
MAKE
)
-C
$$
i
$@
; done
...
...
cppa/context_switching_actor.hpp
View file @
d45b8c6a
...
@@ -31,12 +31,9 @@
...
@@ -31,12 +31,9 @@
#ifndef CPPA_CONTEXT_SWITCHING_ACTOR_HPP
#ifndef CPPA_CONTEXT_SWITCHING_ACTOR_HPP
#define CPPA_CONTEXT_SWITCHING_ACTOR_HPP
#define CPPA_CONTEXT_SWITCHING_ACTOR_HPP
#include "cppa/config.hpp"
#ifndef CPPA_DISABLE_CONTEXT_SWITCHING
#include <stack>
#include <stack>
#include "cppa/config.hpp"
#include "cppa/either.hpp"
#include "cppa/either.hpp"
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
...
@@ -122,6 +119,4 @@ class context_switching_actor : public detail::stacked_actor_mixin<
...
@@ -122,6 +119,4 @@ class context_switching_actor : public detail::stacked_actor_mixin<
}
// namespace cppa
}
// namespace cppa
#endif // CPPA_DISABLE_CONTEXT_SWITCHING
#endif // CPPA_CONTEXT_SWITCHING_ACTOR_HPP
#endif // CPPA_CONTEXT_SWITCHING_ACTOR_HPP
cppa/detail/thread_pool_scheduler.hpp
View file @
d45b8c6a
...
@@ -81,20 +81,6 @@ class thread_pool_scheduler : public scheduler {
...
@@ -81,20 +81,6 @@ class thread_pool_scheduler : public scheduler {
actor_ptr
spawn_as_thread
(
void_function
fun
,
init_callback
cb
,
bool
hidden
);
actor_ptr
spawn_as_thread
(
void_function
fun
,
init_callback
cb
,
bool
hidden
);
# ifndef CPPA_DISABLE_CONTEXT_SWITCHING
template
<
typename
F
>
actor_ptr
spawn_impl
(
void_function
fun
,
scheduling_hint
sh
,
F
cb
)
{
if
(
sh
==
scheduled
)
{
scheduled_actor_ptr
ptr
{
new
context_switching_actor
(
std
::
move
(
fun
))};
ptr
->
attach_to_scheduler
(
this
);
cb
(
ptr
.
get
());
return
spawn_impl
(
std
::
move
(
ptr
));
}
else
{
return
spawn_as_thread
(
std
::
move
(
fun
),
std
::
move
(
cb
));
}
}
# endif
};
};
}
}
// namespace cppa::detail
}
}
// namespace cppa::detail
...
...
cppa/util/fiber.hpp
View file @
d45b8c6a
...
@@ -31,20 +31,6 @@
...
@@ -31,20 +31,6 @@
#ifndef CPPA_FIBER_HPP
#ifndef CPPA_FIBER_HPP
#define CPPA_FIBER_HPP
#define CPPA_FIBER_HPP
#include <memory>
#include "cppa/config.hpp"
#ifdef CPPA_DISABLE_CONTEXT_SWITCHING
namespace
cppa
{
namespace
util
{
class
fiber
{
public:
inline
static
void
swap
(
fiber
&
,
fiber
&
)
{
}
};
}
}
// namespace cppa::util
#else // CPPA_DISABLE_CONTEXT_SWITCHING
namespace
cppa
{
namespace
util
{
namespace
cppa
{
namespace
util
{
struct
fiber_impl
;
struct
fiber_impl
;
...
@@ -69,6 +55,4 @@ class fiber {
...
@@ -69,6 +55,4 @@ class fiber {
}
}
// namespace cppa::util
}
}
// namespace cppa::util
#endif // CPPA_DISABLE_CONTEXT_SWITCHING
#endif // CPPA_FIBER_HPP
#endif // CPPA_FIBER_HPP
src/fiber.cpp
View file @
d45b8c6a
...
@@ -28,17 +28,31 @@
...
@@ -28,17 +28,31 @@
\******************************************************************************/
\******************************************************************************/
#include <cstdint>
#include <stdexcept>
#include "cppa/util/fiber.hpp"
#ifdef CPPA_DISABLE_CONTEXT_SWITCHING
#ifdef CPPA_DISABLE_CONTEXT_SWITCHING
namespace
{
int
keep_compiler_happy
()
{
return
42
;
}
}
namespace
cppa
{
namespace
util
{
fiber
::
fiber
()
throw
()
:
m_impl
(
nullptr
)
{
}
fiber
::
fiber
(
void
(
*
)(
void
*
),
void
*
)
:
m_impl
(
nullptr
)
{
}
fiber
::~
fiber
()
{
}
void
fiber
::
swap
(
fiber
&
,
fiber
&
)
{
throw
std
::
logic_error
(
"libcppa was compiled using "
"CPPA_DISABLE_CONTEXT_SWITCHING"
);
}
}
}
// namespace cppa::util
#else // ifdef CPPA_DISABLE_CONTEXT_SWITCHING
#else // ifdef CPPA_DISABLE_CONTEXT_SWITCHING
#include <cstdint>
#include <boost/context/all.hpp>
#include <boost/context/all.hpp>
#include "cppa/util/fiber.hpp"
namespace
cppa
{
namespace
util
{
namespace
cppa
{
namespace
util
{
void
fiber_trampoline
(
intptr_t
iptr
);
void
fiber_trampoline
(
intptr_t
iptr
);
...
...
src/thread_pool_scheduler.cpp
View file @
d45b8c6a
...
@@ -51,6 +51,24 @@ namespace {
...
@@ -51,6 +51,24 @@ namespace {
typedef
std
::
unique_lock
<
std
::
mutex
>
guard_type
;
typedef
std
::
unique_lock
<
std
::
mutex
>
guard_type
;
typedef
intrusive
::
single_reader_queue
<
thread_pool_scheduler
::
worker
>
worker_queue
;
typedef
intrusive
::
single_reader_queue
<
thread_pool_scheduler
::
worker
>
worker_queue
;
/*
template<typename F>
actor_ptr spawn_void_fun_impl(thread_pool_scheduler* _this,
void_function fun,
scheduling_hint sh,
F cb ) {
if (sh == scheduled) {
scheduled_actor_ptr ptr{new context_switching_actor(std::move(fun))};
ptr->attach_to_scheduler(_this);
cb(ptr.get());
return _this->spawn_impl(std::move(ptr));
}
else {
return _this->spawn_as_thread(std::move(fun), std::move(cb));
}
}
*/
}
// namespace <anonmyous>
}
// namespace <anonmyous>
struct
thread_pool_scheduler
::
worker
{
struct
thread_pool_scheduler
::
worker
{
...
@@ -245,6 +263,7 @@ actor_ptr thread_pool_scheduler::spawn(scheduled_actor* raw, init_callback cb) {
...
@@ -245,6 +263,7 @@ actor_ptr thread_pool_scheduler::spawn(scheduled_actor* raw, init_callback cb) {
}
}
#ifndef CPPA_DISABLE_CONTEXT_SWITCHING
#ifndef CPPA_DISABLE_CONTEXT_SWITCHING
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
fun
,
scheduling_hint
sh
)
{
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
fun
,
scheduling_hint
sh
)
{
if
(
sh
==
scheduled
)
{
if
(
sh
==
scheduled
)
{
scheduled_actor_ptr
ptr
{
new
context_switching_actor
(
std
::
move
(
fun
))};
scheduled_actor_ptr
ptr
{
new
context_switching_actor
(
std
::
move
(
fun
))};
...
@@ -267,17 +286,26 @@ actor_ptr thread_pool_scheduler::spawn(void_function fun,
...
@@ -267,17 +286,26 @@ actor_ptr thread_pool_scheduler::spawn(void_function fun,
return
spawn_impl
(
std
::
move
(
ptr
));
return
spawn_impl
(
std
::
move
(
ptr
));
}
}
else
{
else
{
return
spawn_as_thread
(
std
::
move
(
fun
),
std
::
move
(
init_cb
),
sh
==
detached_and_hidden
);
return
spawn_as_thread
(
std
::
move
(
fun
),
std
::
move
(
init_cb
),
sh
==
detached_and_hidden
);
}
}
}
}
#else
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
what
,
scheduling_hint
)
{
#else // CPPA_DISABLE_CONTEXT_SWITCHING
return
spawn_as_thread
(
std
::
move
(
what
),
[](
local_actor
*
)
{
});
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
what
,
scheduling_hint
sh
)
{
return
spawn_as_thread
(
std
::
move
(
what
),
[](
local_actor
*
)
{
},
sh
==
detached_and_hidden
);
}
}
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
what
,
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
what
,
scheduling_hint
,
scheduling_hint
sh
,
init_callback
init_cb
)
{
init_callback
init_cb
)
{
return
spawn_as_thread
(
std
::
move
(
what
),
std
::
move
(
init_cb
));
return
spawn_as_thread
(
std
::
move
(
what
),
std
::
move
(
init_cb
),
sh
==
detached_and_hidden
);
}
}
#endif
#endif
...
...
unit_testing/test__spawn.cpp
View file @
d45b8c6a
...
@@ -604,6 +604,63 @@ size_t test__spawn() {
...
@@ -604,6 +604,63 @@ size_t test__spawn() {
await_all_others_done
();
await_all_others_done
();
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
auto
inflater
=
factory
::
event_based
(
[](
std
::
string
*
,
actor_ptr
*
receiver
)
{
self
->
become
(
on_arg_match
>>
[
=
](
int
n
,
const
std
::
string
&
s
)
{
send
(
*
receiver
,
n
*
2
,
s
);
},
on
(
atom
(
"done"
))
>>
[]()
{
self
->
quit
();
}
);
}
);
auto
joe
=
inflater
.
spawn
(
"Joe"
,
self
);
auto
bob
=
inflater
.
spawn
(
"Bob"
,
joe
);
send
(
bob
,
1
,
"hello actor"
);
receive
(
on
(
4
,
"hello actor"
)
>>
[]()
{
// done
},
others
()
>>
[]
{
cerr
<<
"unexpected: "
<<
to_string
(
self
->
last_dequeued
())
<<
endl
;
}
);
// kill joe and bob
auto
poison_pill
=
make_any_tuple
(
atom
(
"done"
));
joe
<<
poison_pill
;
bob
<<
poison_pill
;
await_all_others_done
();
std
::
function
<
actor_ptr
(
const
std
::
string
&
,
const
actor_ptr
&
)
>
spawn_next
;
auto
kr34t0r
=
factory
::
event_based
(
// it's safe to pass spawn_next as reference here, because
// - it is guaranteeed to outlive kr34t0r by general scoping rules
// - the lambda is always executed in the current actor's thread
// but using spawn_next in a message handler could
// still cause undefined behavior!
[
&
spawn_next
](
std
::
string
*
name
,
actor_ptr
*
pal
)
{
if
(
*
name
==
"Joe"
&&
!*
pal
)
{
*
pal
=
spawn_next
(
"Bob"
,
self
);
}
self
->
become
(
others
()
>>
[
pal
,
name
]()
{
cout
<<
"hello & bye from "
<<
*
name
<<
endl
;
// forward message and die
*
pal
<<
self
->
last_dequeued
();
self
->
quit
();
}
);
}
);
spawn_next
=
[
&
kr34t0r
](
const
std
::
string
&
name
,
const
actor_ptr
&
pal
)
{
return
kr34t0r
.
spawn
(
name
,
pal
);
};
auto
joe_the_second
=
kr34t0r
.
spawn
(
"Joe"
);
send
(
joe_the_second
,
atom
(
"done"
));
await_all_others_done
();
int
zombie_init_called
=
0
;
int
zombie_init_called
=
0
;
int
zombie_on_exit_called
=
0
;
int
zombie_on_exit_called
=
0
;
factory
::
event_based
([
&
]()
{
factory
::
event_based
([
&
]()
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment