libkoishi: include/koishi.h Source File

libkoishi Decently portable C11 coroutine library |

koishi.h
Go to the documentation of this file.
1
2 #ifndef KOISHI_H
3 #define KOISHI_H
4
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)
13 #else
14 #define KOISHI_API
15 #endif
16 #else
17 #if defined BUILDING_KOISHI && defined __GNUC__
18 #define KOISHI_API __attribute__((visibility("default")))
19 #else
20 #define KOISHI_API
21 #endif
22 #endif
23
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__))
33 #else
34 #define KOISHI_NORETURN
35 #endif
36
37 #if defined BUILDING_KOISHI
38 #include <stddef.h>
39
40 #if defined NDEBUG && (defined __GNUC__ || defined __clang__)
41 #define KOISHI_UNREACHABLE __builtin_unreachable()
42 #else
43 #define KOISHI_UNREACHABLE do { assert(0 && "This code path should never be reached"); abort(); } while(0)
44 #endif
45
46 #ifndef __has_feature
47 #define __has_feature(x) 0 /* compatibility with non-clang compilers */
48 #endif
49
50 #if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer)
51 #include <sanitizer/asan_interface.h>
52 #define KOISHI_ASAN
53 #endif
54
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)
60 #else
61 #define KOISHI_VALGRIND_STACK_ID(name)
62 #define KOISHI_VALGRIND_STACK_REGISTER(id, start, end)
63 #define KOISHI_VALGRIND_STACK_DEREGISTER(id)
64 #endif
65
66 #ifndef offsetof
67 #ifdef __GNUC__
68 #define offsetof(type, field) __builtin_offsetof(type, field)
69 #else
70 #define offsetof(type, field) ((size_t)&(((type *)0)->field))
71 #endif
72 #endif
73 #endif
74
75 #ifdef __cplusplus
76 extern "C" {
77 #endif
78
79 #include <stddef.h>
80
89 enum koishi_state {
90 KOISHI_SUSPENDED,
91 KOISHI_RUNNING,
92 KOISHI_DEAD,
93 KOISHI_IDLE,
94 };
95
101 #ifdef BUILDING_KOISHI
102 typedef struct koishi_coroutine koishi_coroutine_t;
103 struct koishi_coroutine_pub {
104 #else
105 typedef struct koishi_coroutine {
106 #endif
111 void *_private[8];
112 #ifdef BUILDING_KOISHI
113 };
114 #else
115 } koishi_coroutine_t;
116 #endif
117
132 typedef void *(*koishi_entrypoint_t)(void *data);
133
149 KOISHI_API void koishi_init(koishi_coroutine_t *co, size_t min_stack_size, koishi_entrypoint_t entry_point);
150
163 KOISHI_API void koishi_recycle(koishi_coroutine_t *co, koishi_entrypoint_t entry_point);
164
179 KOISHI_API void koishi_deinit(koishi_coroutine_t *co);
180
199 KOISHI_API void *koishi_resume(koishi_coroutine_t *co, void *arg);
200
215 KOISHI_API void *koishi_yield(void *arg);
216
226 KOISHI_API KOISHI_NORETURN void koishi_die(void *arg);
227
243 KOISHI_API void koishi_kill(koishi_coroutine_t *co, void *arg);
244
254 KOISHI_API int koishi_state(koishi_coroutine_t *co);
255
265 KOISHI_API koishi_coroutine_t *koishi_active(void);
266
290 KOISHI_API void *koishi_get_stack(koishi_coroutine_t *co, size_t *stack_size);
291
305 KOISHI_API size_t koishi_util_page_size(void);
306
316 KOISHI_API size_t koishi_util_real_stack_size(size_t min_size);
317
322 #ifdef __cplusplus
323 }
324 #endif
325
326 #endif
koishi_get_stack
KOISHI_API void * koishi_get_stack(koishi_coroutine_t *co, size_t *stack_size)
Query the coroutine's stack region.
koishi_kill
KOISHI_API void koishi_kill(koishi_coroutine_t *co, void *arg)
Stop a coroutine.
koishi_die
KOISHI_API KOISHI_NORETURN void koishi_die(void *arg)
Return from the currently running coroutine.
koishi_active
KOISHI_API koishi_coroutine_t * koishi_active(void)
Query the currently running coroutine context.
koishi_deinit
KOISHI_API void koishi_deinit(koishi_coroutine_t *co)
Deinitialize a koishi_coroutine_t structure.
koishi_init
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
koishi_state
State of a koishi_coroutine_t instance.
Definition: koishi.h:89
koishi_recycle
KOISHI_API void koishi_recycle(koishi_coroutine_t *co, koishi_entrypoint_t entry_point)
Recycle a previously initialized coroutine.
koishi_yield
KOISHI_API void * koishi_yield(void *arg)
Suspend the currently running coroutine.
koishi_entrypoint_t
void *(* koishi_entrypoint_t)(void *data)
A coroutine entry point.
Definition: koishi.h:132
koishi_resume
KOISHI_API void * koishi_resume(koishi_coroutine_t *co, void *arg)
Resume a suspended coroutine.
KOISHI_SUSPENDED
@ KOISHI_SUSPENDED
Definition: koishi.h:90
KOISHI_RUNNING
@ KOISHI_RUNNING
Definition: koishi.h:91
KOISHI_IDLE
@ KOISHI_IDLE
Definition: koishi.h:93
KOISHI_DEAD
@ KOISHI_DEAD
Definition: koishi.h:92
koishi_util_page_size
KOISHI_API size_t koishi_util_page_size(void)
Query the system's page size.
koishi_util_real_stack_size
KOISHI_API size_t koishi_util_real_stack_size(size_t min_size)
Query the real stack size for a given minimum.
KOISHI_NORETURN
#define KOISHI_NORETURN
Annotates API functions that don't return to their callers.
Definition: koishi.h:34
KOISHI_API
#define KOISHI_API
Annotates all publicly visible API functions.
Definition: koishi.h:20
koishi_coroutine_t
A coroutine instance.
Definition: koishi.h:105