Skip to content

Commit

Permalink
coroutines: Added compile-time check in cco_routine(): cco member mus…
Browse files Browse the repository at this point in the history
…t be first in task structs.
  • Loading branch information
Tyge Lovset committed Nov 11, 2024
1 parent ff18a83 commit d2674a8
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 10 deletions.
15 changes: 11 additions & 4 deletions include/stc/coroutine.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef struct {
#define cco_active(co) ((co)->cco.state != CCO_STATE_DONE)

#define cco_routine(co) \
_cco_check_task_struct(co); \
for (int* _state = &(co)->cco.state; *_state != CCO_STATE_DONE; *_state = CCO_STATE_DONE) \
_resume: switch (*_state) case CCO_STATE_INIT: // thanks, @liigo!

Expand Down Expand Up @@ -222,14 +223,20 @@ typedef struct cco_task cco_task;

typedef struct cco_runtime {
int result, top;
struct cco_task* stack[];
cco_task* stack[];
} cco_runtime;

#define cco_cast_task(task) \
((struct cco_task *)(task) + 0*sizeof((task)->cco.func(task, (cco_runtime*)0) + ((int*)0 == &(task)->cco.state)))
((struct cco_task *)(task) + 0*sizeof((task)->cco.func(task, (cco_runtime*)0)))

#define cco_check_task_struct(name) \
(void)c_static_assert(offsetof(struct name, cco.func) == 0);
#if defined __GNUC__ || _MSC_VER >= 1939
#define _cco_check_task_struct(co) \
(void)c_static_assert(/* error: cco not first member in task struct */ \
(sizeof((co)->cco) == sizeof(cco_state) || \
offsetof(__typeof__(*(co)), cco) == 0))
#else
#define _cco_check_task_struct(co) (void)0
#endif

#define cco_resume_task(task, rt) \
(task)->cco.func(task, rt)
Expand Down
2 changes: 1 addition & 1 deletion misc/benchmarks/various/binsearch_bench.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ int main(int argc, char const *argv[])
count += std::binary_search(v.data, v.data + ivec_size(&v), r);
#else
#define LABEL "ivec_binary_search"
count += ivec_binary_search(&v, r) != -1;
count += ivec_binary_search(&v, r) != c_NPOS;
#endif
}
t = clock() - t;
Expand Down
6 changes: 1 addition & 5 deletions misc/examples/coroutines/cotasks2.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

// PRODUCER
cco_task_struct (produce_items) {
produce_items_state cco; // must be first
struct consume_items* consumer;
produce_items_state cco; // must be first
Inventory inv;
int limit, batch, serial, total;
};
Expand All @@ -21,8 +21,6 @@ cco_task_struct (consume_items) {
};

int produce_items(struct produce_items* co, cco_runtime* rt) {
cco_check_task_struct(produce_items); // compile-time check that cco is first member

cco_routine (co) {
while (1) {
if (co->serial > co->total) {
Expand Down Expand Up @@ -53,8 +51,6 @@ int produce_items(struct produce_items* co, cco_runtime* rt) {
}

int consume_items(struct consume_items* co, cco_runtime* rt) {
cco_check_task_struct(consume_items);

cco_routine (co) {
while (1) {
int n = rand() % 10;
Expand Down

0 comments on commit d2674a8

Please sign in to comment.