Lely core libraries 2.3.4
coroutine.h
Go to the documentation of this file.
1
37#ifndef LELY_UTIL_COROUTINE_H_
38#define LELY_UTIL_COROUTINE_H_
39
40#ifndef CO_LABEL_TYPE
46#define CO_LABEL_TYPE int
47#endif
48
53typedef struct {
54 CO_LABEL_TYPE label;
55} co_ctx_t;
56
58#define CO_CTX_INIT \
59 { \
60 0 \
61 }
62
64#define co_restart(ctx) co_restart__(ctx)
65#define co_restart__(ctx) ((void)((ctx)->label = 0))
66
68#define co_is_ready(ctx) co_is_ready__(ctx)
69#define co_is_ready__(ctx) ((ctx)->label == -1)
70
110#define co_reenter(ctx) co_reenter__(ctx)
111#define co_reenter__(ctx) \
112 for (CO_LABEL_TYPE *const _co_label_ = &(ctx)->label; \
113 *_co_label_ != -1; *_co_label_ = -1) \
114 if (0) { \
115 goto _co_continue_; \
116 _co_continue_: \
117 continue; \
118 } else if (0) { \
119 goto _co_break_; \
120 _co_break_: \
121 break; \
122 } else \
123 switch (*_co_label_) \
124 case 0:
125
126#ifdef __COUNTER__
127#define co_label__ (__COUNTER__ + 1)
128#else
129#define co_label__ __LINE__
130#endif
131
143#define co_yield co_yield__(co_label__)
144// clang-format off
145#define co_yield__(label) \
146 for (*_co_label_ = (label);;) \
147 if (0) { \
148 case (label): \
149 break; \
150 } else \
151 switch (0) \
152 for (;;) \
153 if (1) \
154 goto _co_continue_; \
155 else \
156 for (;;) \
157 if (1) \
158 goto _co_break_; \
159 else /* falls through */ \
160 case 0:
161// clang-format on
162
220#define co_fork co_fork__(co_label__)
221#define co_fork__(label) \
222 for (*_co_label_ = -(label)-1;; *_co_label_ = (label)) \
223 if (_co_label_ == (label)) { \
224 case -(label)-1: break; \
225 } else
226
228#define co_is_parent() (!co_is_child())
229
231#define co_is_child() (*_co_label_ < -1)
232
233#endif // !LELY_UTIL_COROUTINE_H_
#define CO_LABEL_TYPE
The type used to store the label (i.e., program counter) of a stackless coroutine.
Definition coroutine.h:46
The type holding the context (i.e., program counter) of a stackless coroutine.
Definition coroutine.h:53