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
d2d24c12
Commit
d2d24c12
authored
Jun 11, 2012
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ported util::fiber to boost.context
parent
ab20ad06
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
40 additions
and
189 deletions
+40
-189
cppa/util/fiber.hpp
cppa/util/fiber.hpp
+6
-41
src/fiber.cpp
src/fiber.cpp
+34
-148
No files found.
cppa/util/fiber.hpp
View file @
d2d24c12
...
...
@@ -31,14 +31,9 @@
#ifndef FIBER_HPP
#define FIBER_HPP
#include <memory>
#include "cppa/config.hpp"
#if defined(CPPA_MACOS) || defined(CPPA_LINUX)
# define CPPA_USE_UCONTEXT_IMPL
#elif defined (CPPA_WINDOWS)
# define CPPA_USE_FIBER_IMPL
#endif
#ifdef CPPA_DISABLE_CONTEXT_SWITCHING
namespace
cppa
{
namespace
util
{
...
...
@@ -48,7 +43,7 @@ class fiber {
};
}
}
// namespace cppa::util
#el
if defined(CPPA_USE_UCONTEXT_IMPL)
#el
se // CPPA_DISABLE_CONTEXT_SWITCHING
namespace
cppa
{
namespace
util
{
...
...
@@ -56,9 +51,7 @@ struct fiber_impl;
class
fiber
{
fiber_impl
*
m_impl
;
public:
public:
fiber
()
throw
();
...
...
@@ -68,42 +61,14 @@ public:
static
void
swap
(
fiber
&
from
,
fiber
&
to
);
};
}
}
// namespace cppa::util
#elif defined(CPPA_USE_FIBER_IMPL)
#include <Winsock2.h>
#include <Windows.h>
namespace
cppa
{
namespace
util
{
class
fiber
{
LPVOID
handle
;
// true if this fiber was created with ConvertThreadToFiber
bool
is_converted_thread
;
void
init
();
public:
private:
fiber
();
fiber
(
LPFIBER_START_ROUTINE
func
,
LPVOID
arg1
);
~
fiber
();
inline
static
void
swap
(
fiber
&
,
fiber
&
to
)
{
SwitchToFiber
(
to
.
handle
);
}
fiber_impl
*
m_impl
;
};
}
}
// namespace cppa::util
#endif // CPPA_USE_UCONTEXT_IMPL
#endif // CPPA_DISABLE_CONTEXT_SWITCHING
#endif // FIBER_HPP
src/fiber.cpp
View file @
d2d24c12
...
...
@@ -28,188 +28,74 @@
\******************************************************************************/
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE
#endif
#ifdef CPPA_DISABLE_CONTEXT_SWITCHING
#include "cppa/config.hpp"
#ifndef CPPA_DISABLE_CONTEXT_SWITCHING
namespace
{
int
keep_compiler_happy
()
{
return
42
;
}
}
#else // ifdef CPPA_DISABLE_CONTEXT_SWITCHING
#include <thread>
#include <atomic>
#include <cstddef>
#include <cstring>
#include <cstdint>
#include <
type_traits
>
#include <
boost/context/all.hpp
>
#include "cppa/util/fiber.hpp"
#ifdef CPPA_USE_UCONTEXT_IMPL
#include <signal.h>
#include <sys/mman.h>
#include <ucontext.h>
namespace
{
constexpr
size_t
s_stack_size
=
SIGSTKSZ
;
typedef
void
(
*
void_function
)();
typedef
void
(
*
void_ptr_function
)(
void
*
);
template
<
size_t
PointerSize
,
typename
FunType
=
void_function
,
typename
IntType
=
int
>
struct
trampoline
;
template
<
typename
FunType
,
typename
IntType
>
struct
trampoline
<
4
,
FunType
,
IntType
>
{
static_assert
(
sizeof
(
int
)
==
4
,
"sizeof(int) != 4"
);
static
void
bounce
(
int
func_ptr
,
int
ptr
)
{
auto
func
=
reinterpret_cast
<
void_ptr_function
>
(
func_ptr
);
func
(
reinterpret_cast
<
void
*>
(
ptr
));
}
static
void
prepare
(
ucontext_t
*
ctx
,
void_ptr_function
func
,
void
*
arg
)
{
makecontext
(
ctx
,
(
FunType
)
&
trampoline
<
4
>::
bounce
,
2
,
(
IntType
)
func
,
(
IntType
)
arg
);
}
};
template
<
typename
FunType
,
typename
IntType
>
struct
trampoline
<
8
,
FunType
,
IntType
>
{
static_assert
(
sizeof
(
int
)
==
4
,
"sizeof(int) != 4"
);
static
void
bounce
(
int
func_first_4_byte
,
int
func_second_4_byte
,
int
arg_first_4_byte
,
int
arg_second_4_byte
)
{
std
::
uint64_t
arg_ptr
;
{
int
*
_addr
=
reinterpret_cast
<
int
*>
(
&
arg_ptr
);
_addr
[
0
]
=
arg_first_4_byte
;
_addr
[
1
]
=
arg_second_4_byte
;
}
std
::
uint64_t
func_ptr
;
{
int
*
_addr
=
reinterpret_cast
<
int
*>
(
&
func_ptr
);
_addr
[
0
]
=
func_first_4_byte
;
_addr
[
1
]
=
func_second_4_byte
;
}
auto
func
=
reinterpret_cast
<
void_ptr_function
>
(
func_ptr
);
func
((
void
*
)
arg_ptr
);
}
static
void
prepare
(
ucontext_t
*
ctx
,
void_ptr_function
func
,
void
*
arg
)
{
std
::
uint64_t
arg_ptr
=
reinterpret_cast
<
std
::
uint64_t
>
(
arg
);
std
::
uint64_t
func_ptr
=
reinterpret_cast
<
std
::
uint64_t
>
(
func
);
int
*
func_addr
=
reinterpret_cast
<
int
*>
(
&
func_ptr
);
int
*
arg_addr
=
reinterpret_cast
<
int
*>
(
&
arg_ptr
);
makecontext
(
ctx
,
(
FunType
)
&
trampoline
<
8
>::
bounce
,
4
,
func_addr
[
0
],
func_addr
[
1
],
arg_addr
[
0
],
arg_addr
[
1
]);
}
};
}
// namespace <anonymous>
namespace
cppa
{
namespace
util
{
void
fiber_trampoline
(
intptr_t
iptr
);
struct
fiber_impl
{
bool
m_initialized
;
void
(
*
m_func
)(
void
*
);
void
*
m_arg
;
void
*
m_stack
;
# ifdef __APPLE__
// ucontext implementation on macosx kinda sucks
static
constexpr
size_t
ucontext_size
=
sizeof
(
ucontext_t
)
+
60
;
char
m_ctx_storage
[
sizeof
(
ucontext_t
)
+
60
];
inline
ucontext_t
*
ctx
()
{
return
reinterpret_cast
<
ucontext_t
*>
(
m_ctx_storage
);
}
# else
static
constexpr
size_t
ucontext_size
=
sizeof
(
ucontext_t
);
ucontext_t
m_ctx
;
inline
ucontext_t
*
ctx
()
{
return
&
m_ctx
;
}
# endif
fiber_impl
()
throw
()
:
m_initialized
(
true
),
m_func
(
0
),
m_arg
(
0
),
m_stack
(
0
)
{
memset
(
ctx
(),
0
,
ucontext_size
);
getcontext
(
ctx
());
}
fiber_impl
(
void
(
*
func
)(
void
*
),
void
*
arg
)
:
m_initialized
(
false
)
,
m_func
(
func
)
,
m_arg
(
arg
)
,
m_stack
(
nullptr
)
{
bool
m_converted
;
void
(
*
m_fun
)(
void
*
);
boost
::
ctx
::
fcontext_t
m_ctx
;
boost
::
ctx
::
stack_allocator
m_alloc
;
fiber_impl
()
:
m_arg
(
nullptr
),
m_converted
(
true
),
m_fun
(
nullptr
)
{
}
fiber_impl
(
void
(
*
fun
)(
void
*
),
void
*
arg
)
:
m_arg
(
arg
),
m_converted
(
false
),
m_fun
(
fun
)
{
auto
st
=
m_alloc
.
allocate
(
boost
::
ctx
::
minimum_stacksize
());
m_ctx
.
fc_stack
.
base
=
st
;
m_ctx
.
fc_stack
.
limit
=
static_cast
<
char
*>
(
st
)
-
boost
::
ctx
::
minimum_stacksize
();
boost
::
ctx
::
make_fcontext
(
&
m_ctx
,
fiber_trampoline
);
}
inline
void
swap
(
fiber_impl
*
to
)
{
swapcontext
(
ctx
(),
to
->
ctx
()
);
inline
void
run
(
)
{
m_fun
(
m_arg
);
}
void
initialize
()
{
m_initialized
=
true
;
memset
(
ctx
(),
0
,
ucontext_size
);
getcontext
(
ctx
());
m_stack
=
malloc
(
s_stack_size
);
ctx
()
->
uc_stack
.
ss_sp
=
m_stack
;
ctx
()
->
uc_stack
.
ss_size
=
s_stack_size
;
ctx
()
->
uc_link
=
nullptr
;
trampoline
<
sizeof
(
void
*
)
>::
prepare
(
ctx
(),
m_func
,
m_arg
);
}
inline
void
lazy_init
()
{
if
(
!
m_initialized
)
initialize
();
void
swap
(
fiber_impl
*
to
)
{
boost
::
ctx
::
jump_fcontext
(
&
m_ctx
,
&
(
to
->
m_ctx
),
(
intptr_t
)
to
);
}
~
fiber_impl
()
{
if
(
m_stack
)
free
(
m_stack
);
if
(
m_converted
==
false
)
{
m_alloc
.
deallocate
(
m_ctx
.
fc_stack
.
base
,
boost
::
ctx
::
minimum_stacksize
());
}
}
};
fiber
::
fiber
()
throw
()
:
m_impl
(
new
fiber_impl
)
{
void
fiber_trampoline
(
intptr_t
iptr
)
{
auto
ptr
=
(
fiber_impl
*
)
iptr
;
ptr
->
run
();
}
fiber
::
fiber
(
void
(
*
func
)(
void
*
),
void
*
arg
)
:
m_impl
(
new
fiber_impl
(
func
,
arg
)
)
{
fiber
::
fiber
(
)
throw
()
:
m_impl
(
new
fiber_impl
)
{
}
fiber
::
~
fiber
()
{
delete
m_impl
;
fiber
::
fiber
(
void
(
*
func
)(
void
*
),
void
*
arg
)
:
m_impl
(
new
fiber_impl
(
func
,
arg
))
{
}
void
fiber
::
swap
(
fiber
&
from
,
fiber
&
to
)
{
to
.
m_impl
->
lazy_init
();
from
.
m_impl
->
swap
(
to
.
m_impl
);
}
}
}
// namespace cppa::util
#elif defined(CPPA_USE_FIBER_IMPL)
#include <stdexcept>
fiber
::
fiber
()
:
handle
(
nullptr
),
is_converted_thread
(
true
)
{
handle
=
ConvertThreadToFiber
(
nullptr
);
if
(
handle
==
nullptr
)
{
throw
std
::
logic_error
(
"handle == nullptr"
);
}
}
fiber
::
fiber
(
LPFIBER_START_ROUTINE
func
,
LPVOID
arg1
)
:
handle
(
nullptr
)
,
is_converted_thread
(
false
)
{
handle
=
CreateFiber
(
0
,
func
,
arg1
);
if
(
handle
==
nullptr
)
{
throw
std
::
logic_error
(
"handle == nullptr"
);
}
}
fiber
::~
fiber
()
{
if
(
handle
!=
nullptr
&&
!
is_converted_thread
)
{
DeleteFiber
(
handle
);
}
delete
m_impl
;
}
#endif // CPPA_USE_FIBER_IMPL
#else // ifdef CPPA_DISABLE_CONTEXT_SWITCHING
namespace
{
int
keep_compiler_happy
()
{
return
42
;
}
}
}
}
// namespace cppa::util
#endif // CPPA_DISABLE_CONTEXT_SWITCHING
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