diff options
| author | tylov <[email protected]> | 2023-07-21 10:49:45 +0200 |
|---|---|---|
| committer | tylov <[email protected]> | 2023-07-21 10:49:45 +0200 |
| commit | dbcc13635402bd466675f4f41e865d02abc6f918 (patch) | |
| tree | 269bbb8e641aaad34b0cca0bbd23c854faa3a960 /include | |
| parent | 2d67f4040f6eecd41f1b864b43c62823ed75aff0 (diff) | |
| download | STC-modified-dbcc13635402bd466675f4f41e865d02abc6f918.tar.gz STC-modified-dbcc13635402bd466675f4f41e865d02abc6f918.zip | |
NB! Changed some coroutine API for consistency/simplicity: Added full task support.
Diffstat (limited to 'include')
| -rw-r--r-- | include/stc/ccommon.h | 2 | ||||
| -rw-r--r-- | include/stc/coroutine.h | 44 |
2 files changed, 23 insertions, 23 deletions
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 1f9ea80d..316a8ee7 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -69,7 +69,7 @@ typedef long long _llong; #define c_new(T, ...) ((T*)memcpy(malloc(sizeof(T)), ((T[]){__VA_ARGS__}), sizeof(T))) #define c_LITERAL(T) (T) #endif -#define c_new_n(T, n) ((T*)malloc(sizeof(T)*(n))) +#define c_new_n(T, n) ((T*)malloc(sizeof(T)*(size_t)(n))) #define c_malloc(sz) malloc(c_i2u(sz)) #define c_calloc(n, sz) calloc(c_i2u(n), c_i2u(sz)) #define c_realloc(p, sz) realloc(p, c_i2u(sz)) diff --git a/include/stc/coroutine.h b/include/stc/coroutine.h index f89d20af..42905744 100644 --- a/include/stc/coroutine.h +++ b/include/stc/coroutine.h @@ -83,26 +83,27 @@ typedef enum { case __LINE__:; \ } while (0) -#define cco_await(promise) cco_await_v_2(promise, CCO_AWAIT) -#define cco_await_v(...) c_MACRO_OVERLOAD(cco_await_v, __VA_ARGS__) -#define cco_await_v_1(promise) cco_await_v_2(promise, ) -#define cco_await_v_2(promise, ret) \ +#define cco_await(promise) cco_await_and_return(promise, CCO_AWAIT) +#define cco_await_v(promise) cco_await_and_return(promise, ) +#define cco_await_and_return(promise, ret) \ do { \ *_state = __LINE__; \ case __LINE__: if (!(promise)) {return ret; goto _resume;} \ } while (0) -/* cco_await_on(): assumes coroutine returns a cco_result value (int) */ -#define cco_await_on(corocall) \ +/* cco_call_await(): assumes coroutine returns a cco_result value (int) */ +#define cco_call_await(...) c_MACRO_OVERLOAD(cco_call_await, __VA_ARGS__) +#define cco_call_await_1(corocall) cco_call_await_2(corocall, CCO_DONE) +#define cco_call_await_2(corocall, resultbits) \ do { \ *_state = __LINE__; \ - case __LINE__: { int _r = corocall; if (_r != CCO_DONE) {return _r; goto _resume;} } \ + case __LINE__: { int _r = corocall; if (!(_r & ~(resultbits))) {return _r; goto _resume;} } \ } while (0) -/* cco_block_on(): assumes coroutine returns a cco_result value (int) */ -#define cco_block_on(...) c_MACRO_OVERLOAD(cco_block_on, __VA_ARGS__) -#define cco_block_on_1(corocall) while ((corocall) != CCO_DONE) -#define cco_block_on_2(corocall, result) while ((*(result) = (corocall)) != CCO_DONE) +/* cco_call_blocking(): assumes coroutine returns a cco_result value (int) */ +#define cco_call_blocking(...) c_MACRO_OVERLOAD(cco_call_blocking, __VA_ARGS__) +#define cco_call_blocking_1(corocall) while ((corocall) != CCO_DONE) +#define cco_call_blocking_2(corocall, result) while ((*(result) = (corocall)) != CCO_DONE) #define cco_cleanup \ *_state = CCO_STATE_CLEANUP; case CCO_STATE_CLEANUP @@ -152,7 +153,7 @@ typedef struct cco_runtime { #define cco_cast_task(task) \ ((cco_task *)(task) + 0*sizeof((task)->cco_func(task, (cco_runtime*)0) + ((int*)0 == &(task)->cco_state))) -#define cco_resume(task, rt) \ +#define cco_task_resume(task, rt) \ (task)->cco_func(task, rt) #define cco_task_await(...) c_MACRO_OVERLOAD(cco_task_await, __VA_ARGS__) @@ -164,11 +165,11 @@ typedef struct cco_runtime { cco_yield_v(CCO_AWAIT); \ } while (0) -#define cco_task_block_on(...) c_MACRO_OVERLOAD(cco_task_block_on, __VA_ARGS__) -#define cco_task_block_on_1(task) cco_task_block_on_3(task, _rt, 16) -#define cco_task_block_on_3(task, rt, STACKDEPTH) \ +#define cco_task_blocking(...) c_MACRO_OVERLOAD(cco_task_blocking, __VA_ARGS__) +#define cco_task_blocking_1(task) cco_task_blocking_3(task, _rt, 16) +#define cco_task_blocking_3(task, rt, STACKDEPTH) \ for (struct { int result, top; cco_task* stack[STACKDEPTH]; } rt = {.stack={cco_cast_task(task)}}; \ - (((rt.result = cco_resume(rt.stack[rt.top], (cco_runtime*)&rt)) & ~rt.stack[rt.top]->cco_expect) || --rt.top >= 0); ) + (((rt.result = cco_task_resume(rt.stack[rt.top], (cco_runtime*)&rt)) & ~rt.stack[rt.top]->cco_expect) || --rt.top >= 0); ) /* * Semaphore @@ -176,12 +177,11 @@ typedef struct cco_runtime { typedef struct { intptr_t count; } cco_sem; -#define cco_sem_await(sem) cco_sem_await_v_2(sem, CCO_AWAIT) -#define cco_sem_await_v(...) c_MACRO_OVERLOAD(cco_sem_await_v, __VA_ARGS__) -#define cco_sem_await_v_1(sem) cco_sem_await_v_2(sem, ) -#define cco_sem_await_v_2(sem, ret) \ +#define cco_sem_await(sem) cco_sem_await_and_return(sem, CCO_AWAIT) +#define cco_sem_await_v(sem) cco_sem_await_and_return(sem, ) +#define cco_sem_await_and_return(sem, ret) \ do { \ - cco_await_v_2((sem)->count > 0, ret); \ + cco_await_and_return((sem)->count > 0, ret); \ --(sem)->count; \ } while (0) @@ -241,7 +241,7 @@ typedef struct { double interval, start; } cco_timer; #define cco_timer_await_v_3(tm, sec, ret) \ do { \ cco_timer_start(tm, sec); \ - cco_await_v_2(cco_timer_expired(tm), ret); \ + cco_await_and_return(cco_timer_expired(tm), ret); \ } while (0) static inline void cco_timer_start(cco_timer* tm, double sec) { |
