Skip to content

Commit

Permalink
add boost_fcontext backend
Browse files Browse the repository at this point in the history
Same as fcontext, but links to the Boost.Context library for the
fcontext asm routines. Requires a C++ compiler.
  • Loading branch information
Akaricchi committed Feb 26, 2023
1 parent 29da5be commit 0b2aecc
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 16 deletions.
7 changes: 6 additions & 1 deletion include/koishi.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
#define offsetof(type, field) ((size_t)&(((type *)0)->field))
#endif
#endif

#ifdef __cplusplus
#undef KOISHI_THREAD_LOCAL
#define KOISHI_THREAD_LOCAL thread_local
#endif
#endif

#ifdef __cplusplus
Expand Down Expand Up @@ -223,7 +228,7 @@ KOISHI_API void *koishi_yield(void *arg);
*
* @param arg Value to return from the corresponding #koishi_resume call.
*/
KOISHI_API KOISHI_NORETURN void koishi_die(void *arg);
KOISHI_NORETURN KOISHI_API void koishi_die(void *arg);

/**
* @brief Stop a coroutine.
Expand Down
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ option(
choices : [
'auto',
'fcontext',
'boost_fcontext',
'win32fiber',
'emscripten',
'ucontext_e2k',
Expand Down
1 change: 1 addition & 0 deletions src/emscripten/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ else
endif

emscripten_src = files('emscripten.c')
emscripten_deps = []
emscripten_args = []
emscripten_external_args = []
emscripten_external_link_args = emscripten_asyncify_args
36 changes: 23 additions & 13 deletions src/fcontext/fcontext.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include "../stack_alloc.h"

typedef struct fcontext *fcontext_t;

typedef struct fcontext_fiber {
fcontext_t fctx;
char *stack;
size_t stack_size;
KOISHI_VALGRIND_STACK_ID(valgrind_stack_id)
} koishi_fiber_t;
#ifdef __cplusplus
extern "C" {
#endif
#include "../stack_alloc.h"
#ifdef __cplusplus
}
#endif

#include "../fiber.h"
#ifndef USE_BOOST_FCONTEXT

typedef struct fcontext *fcontext_t;
typedef struct transfer_t {
fcontext_t fctx;
void *data;
Expand All @@ -27,13 +26,24 @@ fcontext_t FCONTEXT_CALL make_fcontext(void *sp, size_t size, void (*fn)(transfe
// NOTE: currently unused
transfer_t FCONTEXT_CALL ontop_fcontext(const fcontext_t to, void *vp, transfer_t (*fn)(transfer_t));

#endif

typedef struct fcontext_fiber {
fcontext_t fctx;
char *stack;
size_t stack_size;
KOISHI_VALGRIND_STACK_ID(valgrind_stack_id)
} koishi_fiber_t;

#include "../fiber.h"

static void koishi_fiber_swap(koishi_fiber_t *from, koishi_fiber_t *to) {
transfer_t tf = jump_fcontext(to->fctx, from);
from = tf.data;
from = (koishi_fiber_t*)tf.data;
from->fctx = tf.fctx;
}

static KOISHI_NORETURN void co_entry(transfer_t tf) {
KOISHI_NORETURN static void co_entry(transfer_t tf) {
koishi_coroutine_t *co = co_current;
assert(tf.data == &co->caller->fiber);
((koishi_fiber_t*)tf.data)->fctx = tf.fctx;
Expand All @@ -50,7 +60,7 @@ static inline void init_fiber_fcontext(koishi_fiber_t *fiber) {
}

static void koishi_fiber_init(koishi_fiber_t *fiber, size_t min_stack_size) {
fiber->stack = alloc_stack(min_stack_size, &fiber->stack_size);
fiber->stack = (char*)alloc_stack(min_stack_size, &fiber->stack_size);
KOISHI_VALGRIND_STACK_REGISTER(fiber->valgrind_stack_id, fiber->stack, fiber->stack + fiber->stack_size);
init_fiber_fcontext(fiber);
}
Expand Down
1 change: 1 addition & 0 deletions src/fcontext/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ foreach routine : fcontext_asm_routines
endif
endforeach

fcontext_deps = []
fcontext_args = ['-DFCONTEXT_CALL=@0@'.format(fcontext_callconv)]
fcontext_external_args = []
fcontext_external_link_args = []
4 changes: 2 additions & 2 deletions src/fiber.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static void koishi_return_to_caller(koishi_coroutine_t *from, int state) {
koishi_swap_coroutine(from, from->caller, state);
}

static inline KOISHI_NORETURN void koishi_entry(koishi_coroutine_t *co) {
KOISHI_NORETURN static inline void koishi_entry(koishi_coroutine_t *co) {
co->userdata = co->entry(co->userdata);
koishi_return_to_caller(co, KOISHI_DEAD);
KOISHI_UNREACHABLE;
Expand Down Expand Up @@ -98,7 +98,7 @@ KOISHI_API void *koishi_yield(void *arg) {
return co->userdata;
}

KOISHI_API KOISHI_NORETURN void koishi_die(void *arg) {
KOISHI_NORETURN KOISHI_API void koishi_die(void *arg) {
koishi_coroutine_t *co = koishi_active();
co->userdata = arg;
koishi_return_to_caller(co, KOISHI_DEAD);
Expand Down
6 changes: 6 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ koishi_src = files(
'stack_alloc.c',
)

koishi_deps = []

backends = [
'fcontext',
'boost_fcontext',
'win32fiber',
'emscripten',
'ucontext_e2k',
Expand Down Expand Up @@ -41,6 +44,7 @@ if impl == 'auto'
endif

koishi_src += get_variable('@0@_src'.format(impl))
koishi_deps += get_variable('@0@_deps'.format(impl))
koishi_args += get_variable('@0@_args'.format(impl))
koishi_external_args += get_variable('@0@_external_args'.format(impl))
koishi_external_link_args += get_variable('@0@_external_link_args'.format(impl))
Expand All @@ -54,9 +58,11 @@ endif
libkoishi = library('koishi',
koishi_src,
c_args : koishi_args,
cpp_args : koishi_args,
gnu_symbol_visibility : 'hidden',
implicit_include_directories : false,
include_directories : koishi_incdirs,
dependencies : koishi_deps,
install : not meson.is_subproject(),
soversion : soversion,
)
1 change: 1 addition & 0 deletions src/ucontext/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ else
endif

ucontext_src = files('ucontext.c')
ucontext_deps = []
ucontext_args = []
ucontext_external_args = []
ucontext_external_link_args = []
1 change: 1 addition & 0 deletions src/ucontext_e2k/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ foreach fun : ['getcontext', 'makecontext_e2k', 'swapcontext', 'freecontext_e2k'
endforeach

ucontext_e2k_src = files('ucontext_e2k.c')
ucontext_e2k_deps = []
ucontext_e2k_args = []
ucontext_e2k_external_args = []
ucontext_e2k_external_link_args = []
1 change: 1 addition & 0 deletions src/ucontext_sjlj/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ else
endif

ucontext_sjlj_src = files('ucontext_sjlj.c')
ucontext_sjlj_deps = []
ucontext_sjlj_args = ['-U_FORTIFY_SOURCE'] # avoid longjmp false positives
ucontext_sjlj_external_args = []
ucontext_sjlj_external_link_args = []
1 change: 1 addition & 0 deletions src/win32fiber/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
win32fiber_supported = os_is_windows

win32fiber_src = files('win32fiber.c')
win32fiber_deps = []
win32fiber_args = []
win32fiber_external_args = []
win32fiber_external_link_args = []

0 comments on commit 0b2aecc

Please sign in to comment.