summaryrefslogtreecommitdiffhomepage
path: root/include/stc/algo
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-05-24 16:21:22 +0200
committerTyge Løvset <[email protected]>2023-05-24 16:21:22 +0200
commit276b8110033aa275f58ce60d096f220ca050738c (patch)
tree76f5e2c069ecbe268c5497fafafb3b4cb7e66a51 /include/stc/algo
parent8a19b4d6ff098ec014244c86569a7bea2db65514 (diff)
downloadSTC-modified-276b8110033aa275f58ce60d096f220ca050738c.tar.gz
STC-modified-276b8110033aa275f58ce60d096f220ca050738c.zip
coroutine.h:
- Renamed Liigo's coroutine macro cco(x) => cco_routine(x). - Removed cco_begin(x), cco_end() macros. Replaced by cco_routine(x). - Replaced csleep_ms() with csleep_us(), using select() which is portable. - Updated all coroutine examples.
Diffstat (limited to 'include/stc/algo')
-rw-r--r--include/stc/algo/coroutine.h49
1 files changed, 17 insertions, 32 deletions
diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h
index 78dc80c6..ebfed613 100644
--- a/include/stc/algo/coroutine.h
+++ b/include/stc/algo/coroutine.h
@@ -26,31 +26,32 @@
#include <stdio.h>
#include <stc/algo/coroutine.h>
-struct coroutine {
+struct iterpair {
int max_x, max_y;
int x, y;
int cco_state; // required member
};
-bool coroutine(struct coroutine* I) {
- cco_begin(I);
+bool iterpair(struct iterpair* I) {
+ cco_routine(I) {
for (I->x = 0; I->x < I->max_x; I->x++)
for (I->y = 0; I->y < I->max_y; I->y++)
cco_yield(false);
- cco_final: // required if there is cleanup code
+ cco_final: // required if there is cleanup code
puts("final");
- cco_end(true);
+ }
+ return true; // finished
}
int main(void) {
- struct coroutine it = {.max_x=3, .max_y=3};
+ struct iterpair it = {.max_x=3, .max_y=3};
int n = 0;
- while (!coroutine(&it))
+ while (!iterpair(&it))
{
printf("%d %d\n", it.x, it.y);
// example of early stop:
- if (++n == 7) cco_stop(&it); // signal to stop at next
+ if (++n == 7) cco_stop(&it); // signal to stop/finalize in next
}
return 0;
}
@@ -66,19 +67,9 @@ enum {
#define cco_suspended(co) ((co)->cco_state > 0)
#define cco_done(co) ((co)->cco_state == cco_state_done)
-#define cco_begin(co) \
- int *_state = &(co)->cco_state; \
- goto _begin; _begin: switch (*_state) { \
- case 0:
-
-#define cco_end(ret) \
- } \
- *_state = cco_state_done; \
- return ret
-
-#define cco(co) \
+#define cco_routine(co) \
for (int *_state = &(co)->cco_state, _once=1; _once; *_state = cco_state_done, _once=0) \
- _begin: switch (*_state) case 0:
+ _begin: switch (*_state) case 0: // thanks, @liigo!
#define cco_yield(ret) \
do { \
@@ -96,7 +87,7 @@ enum {
#define cco_await_2(promise, ret) \
do { \
*_state = __LINE__; \
- case __LINE__: if (!(promise)) return ret; \
+ case __LINE__: if (!(promise)) {return ret; goto _begin;} \
} while (0)
#define cco_await_coro(...) c_MACRO_OVERLOAD(cco_await_coro, __VA_ARGS__)
@@ -150,18 +141,12 @@ typedef struct {
*/
#include <time.h>
+#include <sys/time.h>
-#ifdef _WIN32
- static inline void csleep_ms(long msecs) {
- extern void Sleep(unsigned long);
- Sleep((unsigned long)msecs);
- }
-#elif _POSIX_C_SOURCE >= 199309L
- static inline void csleep_ms(long msecs) {
- struct timespec ts = {msecs/1000, 1000000*(msecs % 1000)};
- nanosleep(&ts, NULL);
- }
-#endif
+static inline void csleep_us(int64_t usec) {
+ struct timeval tv = {.tv_sec=(int)(usec/1000000), .tv_usec=usec % 1000000};
+ select(0, NULL, NULL, NULL, &tv);
+}
typedef struct {
clock_t start;