Skip to content

Commit

Permalink
Reverted cco_final: => cco_cleanup: . More descriptive. cco_final dep…
Browse files Browse the repository at this point in the history
…recated.
  • Loading branch information
tylov committed Oct 23, 2024
1 parent 212c03d commit 3c3b5be
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 51 deletions.
14 changes: 7 additions & 7 deletions docs/coroutine_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ NB! ***cco_yield\*()*** / ***cco_await\*()*** may not be called from within a `s
| | Function / operator | Description |
|:----------|:-------------------------------------|:----------------------------------------|
|`cco_result` | `CCO_DONE`, `CCO_AWAIT`, `CCO_YIELD` | Default set of return values from coroutines |
| | `cco_final:` | Label for cleanup position in coroutine |
| | `cco_cleanup:` | Label for cleanup position in coroutine |
| `bool` | `cco_done(co)` | Is coroutine done? |
| | `cco_scope(co) {}` | The coroutine scope |
| | `cco_yield;` | Yield/suspend execution (return CCO_YIELD)|
Expand Down Expand Up @@ -105,13 +105,13 @@ int triples(struct triples* i) {
(int64_t)i->c * i->c)
{
if (i->c > i->max_c)
cco_return; // "jump" to cco_final if defined, else exit scope.
cco_return; // "jump" to cco_cleanup if defined, else exit scope.
cco_yield;
}
}
}
}
cco_final:
cco_cleanup:
puts("done");
}
return 0; // CCO_DONE
Expand Down Expand Up @@ -164,7 +164,7 @@ int gcd1_triples(struct gcd1_triples* i)
else
cco_yield;
}
cco_final:
cco_cleanup:
cco_stop(&i->tri); // to cleanup state if still active
triples(&i->tri); // do cleanup (or no-op if done)
}
Expand Down Expand Up @@ -207,7 +207,7 @@ by awaiting a few seconds before producing a number, using a timer.
#include "stc/coroutine.h"

cco_task_struct (next_value) {
next_value_state cco;
next_value_state cco; // must be first member!
int val;
cco_timer tm;
};
Expand Down Expand Up @@ -253,7 +253,7 @@ int produce_items(struct produce_items* p, cco_runtime* rt)
printf("produced %s\n", cstr_str(&p->text));
cco_yield;
}
cco_final:
cco_cleanup:
cstr_drop(&p->text);
puts("done produce");
}
Expand All @@ -279,7 +279,7 @@ int consume_items(struct consume_items* c, cco_runtime* rt)
print_time();
printf("consumed %s\n", cstr_str(&c->produce.text));
}
cco_final:
cco_cleanup:
cco_stop(&c->produce);
cco_resume_task(&c->produce, rt);
puts("done consume");
Expand Down
60 changes: 33 additions & 27 deletions include/stc/coroutine.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ int iterpair(struct iterpair* I) {
for (I->y = 0; I->y < I->max_y; I->y++)
cco_yield;
cco_final: // required if there is cleanup code
cco_cleanup: // required if there is cleanup code
puts("final");
}
return 0; // CCO_DONE
Expand All @@ -60,7 +60,7 @@ int main(void) {

enum {
CCO_STATE_INIT = 0,
CCO_STATE_FINAL = -1,
CCO_STATE_CLEANUP = -1,
CCO_STATE_DONE = -2,
};
typedef enum {
Expand All @@ -81,7 +81,20 @@ typedef struct {
#define cco_scope(co) \
for (int* _state = &(co)->cco.state; *_state != CCO_STATE_DONE; *_state = CCO_STATE_DONE) \
_resume: switch (*_state) case CCO_STATE_INIT: // thanks, @liigo!

#define cco_cleanup \
*_state = CCO_STATE_CLEANUP; \
/* fall through */ \
case CCO_STATE_CLEANUP

#define cco_routine cco_scope // [deprecated]
#define cco_final cco_cleanup // [deprecated]

#define cco_return \
do { \
*_state = *_state >= CCO_STATE_INIT ? CCO_STATE_CLEANUP : CCO_STATE_DONE; \
goto _resume; \
} while (0)

#define cco_yield cco_yield_v(CCO_YIELD)
#define cco_yield_v(ret) \
Expand All @@ -93,7 +106,7 @@ typedef struct {
#define cco_yield_final cco_yield_final_v(CCO_YIELD)
#define cco_yield_final_v(value) \
do { \
*_state = *_state >= CCO_STATE_INIT ? CCO_STATE_FINAL : CCO_STATE_DONE; \
*_state = *_state >= CCO_STATE_INIT ? CCO_STATE_CLEANUP : CCO_STATE_DONE; \
return value; \
} while (0)

Expand All @@ -112,30 +125,23 @@ typedef struct {
do { \
*_state = __LINE__; \
/* fall through */ \
case __LINE__: { int _r = corocall; if (_r & ~(awaitbits)) {return _r; goto _resume;} } \
case __LINE__: { \
int _r = corocall; \
if (_r & ~(awaitbits)) { return _r; goto _resume; } \
} \
} while (0)

/* cco_run_coroutine(): assumes coroutine returns a cco_result value (int) */
#define cco_run_coroutine(corocall) while ((1 ? (corocall) : -1) != CCO_DONE)

#define cco_final \
*_state = CCO_STATE_FINAL; \
/* fall through */ \
case CCO_STATE_FINAL

#define cco_return \
do { \
*_state = *_state >= CCO_STATE_INIT ? CCO_STATE_FINAL : CCO_STATE_DONE; \
goto _resume; \
} while (0)
#define cco_run_coroutine(corocall) \
while ((1 ? (corocall) : -1) != CCO_DONE)

#define cco_stop(co) \
((co)->cco.state = (co)->cco.state >= CCO_STATE_INIT ? CCO_STATE_FINAL : CCO_STATE_DONE)
((co)->cco.state = (co)->cco.state >= CCO_STATE_INIT ? \
CCO_STATE_CLEANUP : CCO_STATE_DONE)

#define cco_reset(co) \
(void)((co)->cco.state = 0)


/* ============ ADVANCED, OPTIONAL ============= */

/*
Expand All @@ -144,11 +150,7 @@ typedef struct {
* Gen_iter Gen_begin(Gen* g); // return a coroutine object, advanced to the first yield
* int Gen_next(Gen_iter* it); // resume the coroutine
*
* Gen_iter Gen_begin(Gen* g) { // basic implementation
* Gen_iter it = {.ref=g};
* Gen_next(&it);
* return it;
* }
* cco_default_begin(Gen); // implements basic Gen_begin() function
* ....
* c_foreach (i, Gen, gen)
printf("%d ", *i.ref);
Expand All @@ -169,8 +171,11 @@ Gen##_iter Gen##_begin(Gen* g) { \

/* Using c_filter with generators:
*/
#define cco_flt_take(n) (c_flt_take(n), _base.done ? _it.cco.state = CCO_STATE_FINAL : 1)
#define cco_flt_takewhile(pred) (c_flt_takewhile(pred), _base.done ? _it.cco.state = CCO_STATE_FINAL : 1)
#define cco_flt_take(n) \
(c_flt_take(n), _base.done ? _it.cco.state = CCO_STATE_CLEANUP : 1)

#define cco_flt_takewhile(pred) \
(c_flt_takewhile(pred), _base.done ? _it.cco.state = CCO_STATE_CLEANUP : 1)


/*
Expand Down Expand Up @@ -212,9 +217,10 @@ typedef struct cco_runtime {
#define cco_run_task(...) c_MACRO_OVERLOAD(cco_run_task, __VA_ARGS__)
#define cco_run_task_1(task) cco_run_task_3(task, _rt, 16)
#define cco_run_task_3(task, rt, STACKDEPTH) \
for (struct { int result, top; struct cco_task* stack[STACKDEPTH]; } rt = {.stack={cco_cast_task(task)}}; \
for (struct { int result, top; struct cco_task* stack[STACKDEPTH]; } \
rt = {.stack = {cco_cast_task(task)}} ; \
(((rt.result = cco_resume_task(rt.stack[rt.top], (cco_runtime*)&rt)) & \
~rt.stack[rt.top]->cco.expect) || --rt.top >= 0); )
~rt.stack[rt.top]->cco.expect) || --rt.top >= 0) ; )

/*
* Iterate containers with already defined iterator (prefer to use in coroutines only):
Expand Down
2 changes: 1 addition & 1 deletion include/stc/zsview.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ STC_INLINE zsview zsview_from(const char* str)
STC_INLINE void zsview_clear(zsview* self) { *self = c_zv(""); }
STC_INLINE csview zsview_sv(zsview zs) { return c_sv_2(zs.str, zs.size); }

STC_INLINE isize zsview_size(zsview zs) { return zs.size; }
STC_INLINE isize zsview_size(zsview zs) { return zs.size; }
STC_INLINE bool zsview_is_empty(zsview zs) { return zs.size == 0; }

STC_INLINE bool zsview_equals(zsview zs, const char* str) {
Expand Down
2 changes: 1 addition & 1 deletion misc/examples/coroutines/coread.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ int file_read(struct file_read* g)

cco_await( !cstr_getline(&g->line, g->fp) );

cco_final:
cco_cleanup:
printf("finish\n");
cstr_drop(&g->line);
if (g->fp) fclose(g->fp);
Expand Down
8 changes: 4 additions & 4 deletions misc/examples/coroutines/coroutines.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ int prime(struct prime* g) {
cco_yield_v(YIELD_PRM);
}
}
cco_final:
cco_cleanup:
puts("DONE prm");
}
return 0;
Expand Down Expand Up @@ -64,7 +64,7 @@ int fibonacci(struct fibonacci* g) {
g->b += tmp;
cco_yield_v(YIELD_FIB);
}
cco_final:
cco_cleanup:
puts("DONE fib");
}
return 0;
Expand All @@ -83,7 +83,7 @@ int sequenced(struct combined* g) {
cco_await_coroutine( prime(&g->prm) );
cco_await_coroutine( fibonacci(&g->fib) );

cco_final:
cco_cleanup:
puts("DONE sequenced");
}
return 0;
Expand All @@ -93,7 +93,7 @@ int parallel(struct combined* g) {
cco_scope(g) {
cco_await_coroutine( prime(&g->prm) | fibonacci(&g->fib) );

cco_final:
cco_cleanup:
puts("DONE parallel");
}
return 0;
Expand Down
4 changes: 2 additions & 2 deletions misc/examples/coroutines/cotasks1.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int produce_items(struct produce_items* p)
printf("produced %s\n", cstr_str(&p->text));
cco_yield;
}
cco_final:
cco_cleanup:
cstr_drop(&p->text);
puts("done produce");
}
Expand All @@ -75,7 +75,7 @@ int consume_items(struct consume_items* c, struct produce_items* p)
print_time();
printf("consumed %s\n", cstr_str(&p->text));
}
cco_final:
cco_cleanup:
puts("done consume");
}
return 0;
Expand Down
4 changes: 2 additions & 2 deletions misc/examples/coroutines/cotasks2.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ int produce_items(struct produce_items* p, cco_runtime* rt)
cco_yield;
}

cco_final:
cco_cleanup:
cstr_drop(&p->text);
puts("done produce");
}
Expand Down Expand Up @@ -83,7 +83,7 @@ int consume_items(struct consume_items* c, cco_runtime* rt)
printf("consumed %s\n", cstr_str(&c->produce.text));
}

cco_final:
cco_cleanup:
cco_stop(&c->produce);
cco_resume_task(&c->produce, rt);
puts("done consume");
Expand Down
4 changes: 2 additions & 2 deletions misc/examples/coroutines/dining_philosophers.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ int philosopher(struct Philosopher* p)
cco_semaphore_release(p->right_fork);
}

cco_final:
cco_cleanup:
printf("Philosopher %d finished\n", p->id);
}
return 0;
Expand Down Expand Up @@ -76,7 +76,7 @@ int dining(struct Dining* d)
cco_yield; // suspend, return control back to main
}

cco_final:
cco_cleanup:
for (int i = 0; i < num_philosophers; ++i) {
cco_stop(&d->ph[i]);
philosopher(&d->ph[i]);
Expand Down
2 changes: 1 addition & 1 deletion misc/examples/coroutines/fibonacci.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ int fibonacci(struct fibonacci* g) {
cco_yield;
}

cco_final:
cco_cleanup:
puts("done");
}
return 0;
Expand Down
4 changes: 2 additions & 2 deletions misc/examples/coroutines/filetask.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int file_read(struct file_read* co, cco_runtime* rt)
cco_yield;
}

cco_final:
cco_cleanup:
fclose(co->fp);
cstr_drop(&co->line);
puts("done file_read");
Expand Down Expand Up @@ -61,7 +61,7 @@ int count_line(struct count_line* co, cco_runtime* rt)
cco_yield;
}

cco_final:
cco_cleanup:
cstr_drop(&co->path);
puts("done count_line");
}
Expand Down
2 changes: 1 addition & 1 deletion misc/examples/coroutines/generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ int Triple_next(Triple_iter* it) {
}
}
}
cco_final: // cleanup
cco_cleanup:
it->ref = NULL; // stop iteration
printf("Done\n");
}
Expand Down
2 changes: 1 addition & 1 deletion misc/examples/coroutines/triples.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ int triples_coro(struct triples* t) {
}
}
}
cco_final:
cco_cleanup:
puts("done");
}
return 0;
Expand Down

0 comments on commit 3c3b5be

Please sign in to comment.