diff options
| author | Tyge Løvset <[email protected]> | 2023-05-08 07:40:41 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-05-08 07:40:41 +0200 |
| commit | bca31bb8d85d6781f0c3d074eb1a25fa6de48e07 (patch) | |
| tree | e4938ea3acf08bcdd31f003c1e83f9b1ab29e0dc | |
| parent | b03148caa1d6fc660e6e7c5986dd6fd38779bedc (diff) | |
| download | STC-modified-bca31bb8d85d6781f0c3d074eb1a25fa6de48e07.tar.gz STC-modified-bca31bb8d85d6781f0c3d074eb1a25fa6de48e07.zip | |
Updated API for timer and semaphores in coroutine.h (ctimer, csem)
| -rw-r--r-- | docs/ccommon_api.md | 17 | ||||
| -rw-r--r-- | include/stc/algo/coroutine.h | 68 |
2 files changed, 66 insertions, 19 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 2319109b..c20043f8 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -362,12 +362,21 @@ To resume the coroutine from where it was suspended with *cco_yield()*, simply c | | `cco_yield()` | Suspend execution | | | `cco_yield(retval)` | Suspend execution and return retval | | | `cco_await(promise)` | Suspend until promise is true | -| | `cco_await_with(promise, retval)` | Suspend with retval until promise is true | +| | `cco_await(promise, retval)` | Suspend with retval until promise is true | | | Semaphores: | | -| | `cco_semaphore` | Semaphore type | +| | `csem` | Semaphore type | | | `cco_await_sem(sem)` | Await for the semaphore count > 0 | -| | `cco_await_sem_with(sem, retval)` | Await with retval for the semaphore | -| | `cco_signal_sem(sem)` | Signal the semaphore by increasing count| +| | `cco_await_sem(sem, retval)` | Await with retval for the semaphore | +| | `csem_set(sem, long value)` | Set semaphore | +| | `csem_signal(sem)` | Signal the semaphore | +| | Timers: | | +| | `ctimer` | Timer type | +| | `cco_await_timer(tm)` | Await for timer to expire | +| | `cco_await_timer(tm, retval)` | Await with retval for timer to expire | +| | `ctimer_start(tm, long msecs)` | Start timer for milliseconds | +| | `ctimer_restart(tm)` | Restart timer with same duration | +| `bool` | `ctimer_expired(tm)` | Return true if timer is expired | +| `long` | `ctimer_remaining(tm)` | Return milliseconds remaining | | | From caller side: | | | `void` | `cco_stop(ctx)` | Next call of coroutine returns `cco_end()` | | `void` | `cco_reset(ctx)` | Reset state to initial (for reuse) | diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index c9cb8fc0..80b96bbd 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -108,17 +108,14 @@ enum { if (*_state == cco_state_done) *_state = 0; \ } while (0) +/* + * Semaphore + */ typedef struct { intptr_t count; -} cco_semaphore; +} csem; -/** - * Wait for a semaphore - * - * This macro carries out the "wait" operation on the semaphore, - * and causes the "thread" to block while the counter is zero. - */ #define cco_await_sem(...) c_MACRO_OVERLOAD(cco_await_sem, __VA_ARGS__) #define cco_await_sem_1(sem) cco_await_sem_2(sem, ) #define cco_await_sem_2(sem, retval) \ @@ -127,14 +124,55 @@ typedef struct { --(sem)->count; \ } while (0) -/** - * Signal a semaphore - * - * This macro carries out the "signal" operation on the semaphore, - * and increments the counter inside the semaphore, which - * eventually will cause waiting "threads" to continue executing. +#define csem_signal(sem) ++(sem)->count +#define csem_set(sem, value) ((sem)->count = (value)) + +/* + * Timer */ -#define cco_signal_sem(sem) ++(sem)->count -#define cco_reset_sem(sem, value) ((sem)->count = (value)) + +#include <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 + +typedef struct { + clock_t start; + clock_t interval; +} ctimer; + +#define cco_await_timer(...) c_MACRO_OVERLOAD(cco_await_timer, __VA_ARGS__) +#define cco_await_timer_2(t, msecs) cco_await_timer_3(t, msecs, ) +#define cco_await_timer_3(t, msecs, ret) \ + do { \ + ctimer_start(t, msecs); \ + cco_await_2(ctimer_expired(t), ret); \ + } while (0) + +static inline void ctimer_start(ctimer* t, long msecs) { + t->interval = msecs*(CLOCKS_PER_SEC/1000); + t->start = clock(); +} + +static inline void ctimer_restart(ctimer* t) { + t->start = clock(); +} + +static inline bool ctimer_expired(ctimer* t) { + return clock() - t->start >= t->interval; +} + +static inline long ctimer_remaining(ctimer* t) { + return (long)((double)(t->start + t->interval - clock())*(1000.0/CLOCKS_PER_SEC)); +} #endif |
