8 #if defined _WIN32 || defined __CYGWIN__
9 #if defined BUILDING_KOISHI
10 #define KOISHI_API __declspec(dllexport)
11 #elif defined KOISHI_DLLIMPORT
12 #define KOISHI_API __declspec(dllimport)
17 #if defined BUILDING_KOISHI && defined __GNUC__
18 #define KOISHI_API __attribute__((visibility("default")))
27 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L
28 #define KOISHI_NORETURN _Noreturn
29 #elif defined __cplusplus && __cplusplus >= 201103L
30 #define KOISHI_NORETURN [[noreturn]]
31 #elif defined __GNUC__ || defined __clang__
32 #define KOISHI_NORETURN __attribute__((__noreturn__))
34 #define KOISHI_NORETURN
37 #if defined BUILDING_KOISHI
40 #if defined NDEBUG && (defined __GNUC__ || defined __clang__)
41 #define KOISHI_UNREACHABLE __builtin_unreachable()
43 #define KOISHI_UNREACHABLE do { assert(0 && "This code path should never be reached"); abort(); } while(0)
47 #define __has_feature(x) 0
50 #if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
51 #include <sanitizer/asan_interface.h>
55 #if defined(KOISHI_VALGRIND)
56 #include <valgrind/valgrind.h>
57 #define KOISHI_VALGRIND_STACK_ID(name) int name;
58 #define KOISHI_VALGRIND_STACK_REGISTER(id, start, end) id = VALGRIND_STACK_REGISTER(start, end)
59 #define KOISHI_VALGRIND_STACK_DEREGISTER(id) VALGRIND_STACK_DEREGISTER(id)
61 #define KOISHI_VALGRIND_STACK_ID(name)
62 #define KOISHI_VALGRIND_STACK_REGISTER(id, start, end)
63 #define KOISHI_VALGRIND_STACK_DEREGISTER(id)
68 #define offsetof(type, field) __builtin_offsetof(type, field)
70 #define offsetof(type, field) ((size_t)&(((type *)0)->field))
101 #ifdef BUILDING_KOISHI
103 struct koishi_coroutine_pub {
105 typedef struct koishi_coroutine {
112 #ifdef BUILDING_KOISHI
132 typedef void *(*koishi_entrypoint_t)(
void *data);
KOISHI_API void * koishi_get_stack(koishi_coroutine_t *co, size_t *stack_size)
Query the coroutine's stack region.
KOISHI_API void koishi_kill(koishi_coroutine_t *co, void *arg)
Stop a coroutine.
KOISHI_API KOISHI_NORETURN void koishi_die(void *arg)
Return from the currently running coroutine.
KOISHI_API koishi_coroutine_t * koishi_active(void)
Query the currently running coroutine context.
KOISHI_API void koishi_deinit(koishi_coroutine_t *co)
Deinitialize a koishi_coroutine_t structure.
KOISHI_API void koishi_init(koishi_coroutine_t *co, size_t min_stack_size, koishi_entrypoint_t entry_point)
Initialize a koishi_coroutine_t structure.
koishi_state
State of a koishi_coroutine_t instance.
KOISHI_API void koishi_recycle(koishi_coroutine_t *co, koishi_entrypoint_t entry_point)
Recycle a previously initialized coroutine.
KOISHI_API void * koishi_yield(void *arg)
Suspend the currently running coroutine.
void *(* koishi_entrypoint_t)(void *data)
A coroutine entry point.
KOISHI_API void * koishi_resume(koishi_coroutine_t *co, void *arg)
Resume a suspended coroutine.
KOISHI_API size_t koishi_util_page_size(void)
Query the system's page size.
KOISHI_API size_t koishi_util_real_stack_size(size_t min_size)
Query the real stack size for a given minimum.
#define KOISHI_NORETURN
Annotates API functions that don't return to their callers.
#define KOISHI_API
Annotates all publicly visible API functions.