diff options
| author | Tyge Løvset <[email protected]> | 2023-06-07 10:35:38 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-06-07 19:56:11 +0200 |
| commit | 56469c2738effe6d44a3a0c44e821c0ff18ce28e (patch) | |
| tree | 3bfe712740a7f4bd6cbfcea115b581def9071828 | |
| parent | 7c57f4fb7edf33d030975a04160f183f71c48ecd (diff) | |
| download | STC-modified-56469c2738effe6d44a3a0c44e821c0ff18ce28e.tar.gz STC-modified-56469c2738effe6d44a3a0c44e821c0ff18ce28e.zip | |
cco: Minor internal cleanup + added cco_timer_elapsed().
| -rw-r--r-- | docs/ccommon_api.md | 9 | ||||
| -rw-r--r-- | include/stc/algo/coroutine.h | 27 | ||||
| -rw-r--r-- | misc/examples/dining_philosophers.c | 7 |
3 files changed, 22 insertions, 21 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index 1fd8af75..930b8881 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -385,14 +385,15 @@ To resume the coroutine from where it was suspended with *cco_yield()*, simply c | | `cco_sem_await(sem)` | Await for the semaphore count > 0 | | | `cco_sem_await(sem, ret)` | Await with ret on the semaphore | | `cco_sem` | `cco_sem_init(long value)` | Set semaphore value | -| | `cco_sem_release(sem)` | Signal the semaphore | +| | `cco_sem_release(sem)` | Signal the semaphore (count += 1) | | | Timers: | | | | `cco_timer` | Timer type | -| | `cco_timer_await(tm)` | Await for timer to expire | -| | `cco_timer_await(tm, ret)` | Await with ret for timer to expire | -| | `cco_timer_start(tm, double sec)` | Start timer for sec seconds (usec prec.)| +| | `cco_timer_await(tm, double sec)` | Await secs for timer to expire (usec prec.)| +| | `cco_timer_await(tm, double sec, ret)`| Await secs for timer with ret value | +| | `cco_timer_start(tm, double sec)` | Start timer for secs duration | | | `cco_timer_restart(tm)` | Restart timer with same duration | | `bool` | `cco_timer_expired(tm)` | Return true if timer is expired | +| `double` | `cco_timer_elapsed(tm)` | Return seconds elapsed | | `double` | `cco_timer_remaining(tm)` | Return seconds remaining | | | From caller side: | | | `void` | `cco_stop(co)` | Next call of coroutine finalizes | diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index f03fc836..81c75aa1 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -67,12 +67,12 @@ enum { #define cco_done(co) ((co)->cco_state == cco_state_done) #define cco_routine(co) \ - for (int *_state = &(co)->cco_state, _once=1; _once; *_state = cco_state_done, _once=0) \ - _begin: switch (*_state) case 0: // thanks, @liigo! + for (int *_state = &(co)->cco_state; *_state != cco_state_done; *_state = cco_state_done) \ + _resume: switch (*_state) case 0: // thanks, @liigo! #define cco_yield(ret) \ do { \ - *_state = __LINE__; return ret; goto _begin; \ + *_state = __LINE__; return ret; goto _resume; \ case __LINE__:; \ } while (0) @@ -81,7 +81,7 @@ enum { #define cco_await_2(promise, ret) \ do { \ *_state = __LINE__; \ - case __LINE__: if (!(promise)) {return ret; goto _begin;} \ + case __LINE__: if (!(promise)) {return ret; goto _resume;} \ } while (0) #define cco_run(co, call) while (call, !cco_done(co)) @@ -91,13 +91,13 @@ enum { #define cco_return \ do { \ - *_state = *_state < 0 ? cco_state_done : cco_state_final; \ - goto _begin; \ + *_state = *_state >= 0 ? cco_state_final : cco_state_done; \ + goto _resume; \ } while (0) #define cco_return_v(value) \ do { \ - *_state = *_state < 0 ? cco_state_done : cco_state_final; \ + *_state = *_state >= 0 ? cco_state_final : cco_state_done; \ return value; \ } while (0) @@ -115,9 +115,7 @@ enum { * Semaphore */ -typedef struct { - intptr_t count; -} cco_sem; +typedef struct { intptr_t count; } cco_sem; #define cco_sem_await(...) c_MACRO_OVERLOAD(cco_sem_await, __VA_ARGS__) #define cco_sem_await_1(sem) cco_sem_await_2(sem, ) @@ -146,10 +144,9 @@ typedef struct { _c_LINKC void Sleep(unsigned long); static inline double cco_time(void) { /* seconds since epoch */ - static const unsigned long long epoch_offset = 116444736000000000ULL; /* 1/10th usecs betweeen Jan 1,1601 - Jan 1,1970 */ - unsigned long long quad; /* 64-bit value, 100-nanosecond intervals since January 1, 1601 00:00 UTC */ + unsigned long long quad; /* 64-bit value representing 1/10th usecs since Jan 1 1601, 00:00 UTC */ GetSystemTimePreciseAsFileTime((struct _FILETIME*)&quad); - return (double)(quad - epoch_offset)*1e-7; + return (double)(quad - 116444736000000000ULL)*1e-7; /* time diff Jan 1 1601-Jan 1 1970 in 1/10th usecs */ } static inline void cco_sleep(double sec) { @@ -199,6 +196,10 @@ static inline bool cco_timer_expired(cco_timer* tm) { return cco_time() - tm->start >= tm->interval; } +static inline double cco_timer_elapsed(cco_timer* tm) { + return cco_time() - tm->start; +} + static inline double cco_timer_remaining(cco_timer* tm) { return tm->start + tm->interval - cco_time(); } diff --git a/misc/examples/dining_philosophers.c b/misc/examples/dining_philosophers.c index 57fcef56..f9c05e71 100644 --- a/misc/examples/dining_philosophers.c +++ b/misc/examples/dining_philosophers.c @@ -22,7 +22,6 @@ struct Dining { // Define semaphores for the forks cco_sem forks[num_forks]; struct Philosopher ph[num_philosophers]; - int ph_idx; int cco_state; // required }; @@ -43,7 +42,7 @@ void philosopher(struct Philosopher* p) duration = 0.5 + crandf(); printf("Philosopher %d is eating for %.0f minutes...\n", p->id, duration*10); cco_timer_await(&p->tm, duration); - + cco_sem_release(p->left_fork); cco_sem_release(p->right_fork); } @@ -69,8 +68,8 @@ void dining(struct Dining* d) while (1) { // per-"frame" logic update of all philosophers states - for (d->ph_idx = 0; d->ph_idx < num_philosophers; ++d->ph_idx) { - philosopher(&d->ph[d->ph_idx]); + for (int i = 0; i < num_philosophers; ++i) { + philosopher(&d->ph[i]); } cco_yield(); // suspend, return control back to main } |
