diff options
| author | Tyge Løvset <[email protected]> | 2023-06-05 19:02:03 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-06-05 19:13:22 +0200 |
| commit | 4b8f8d2a97ca1411ad6dccdeac6195574edac852 (patch) | |
| tree | c744f00c4288d3e8988a07b417c754ca5db17f4a /include | |
| parent | 2d3250d2d35dda415840d8403b7b8957ca40914a (diff) | |
| download | STC-modified-4b8f8d2a97ca1411ad6dccdeac6195574edac852.tar.gz STC-modified-4b8f8d2a97ca1411ad6dccdeac6195574edac852.zip | |
Updated timers and time functions to microseconds (from milli).
Diffstat (limited to 'include')
| -rw-r--r-- | include/stc/algo/coroutine.h | 79 |
1 files changed, 50 insertions, 29 deletions
diff --git a/include/stc/algo/coroutine.h b/include/stc/algo/coroutine.h index 05307b08..d0c9ad86 100644 --- a/include/stc/algo/coroutine.h +++ b/include/stc/algo/coroutine.h @@ -56,7 +56,6 @@ int main(void) { return 0; } */ -#include <time.h> #include <stc/ccommon.h> enum { @@ -130,55 +129,77 @@ typedef struct { * Timer */ -typedef struct { - clock_t start; - clock_t interval; -} cco_timer; - -#define cco_timer_await(...) c_MACRO_OVERLOAD(cco_timer_await, __VA_ARGS__) -#define cco_timer_await_2(tm, msec) cco_timer_await_3(tm, msec, ) -#define cco_timer_await_3(tm, msec, ret) \ - do { \ - cco_timer_start(tm, msec); \ - cco_await_2(cco_timer_expired(tm), ret); \ - } while (0) - #ifdef _WIN32 #ifdef __cplusplus - extern "C" + #define _c_LINKC extern "C" __declspec(dllimport) + #else + #define _c_LINKC __declspec(dllimport) #endif - __declspec(dllimport) void __stdcall Sleep(unsigned long); - static inline void cco_sleep(long msec) { - Sleep((unsigned long)msec); + struct _FILETIME; struct _SECURITY_ATTRIBUTES; union _LARGE_INTEGER; + _c_LINKC void GetSystemTimePreciseAsFileTime(struct _FILETIME*); + _c_LINKC void* CreateWaitableTimerW(struct _SECURITY_ATTRIBUTES*, int, const wchar_t*); + _c_LINKC int SetWaitableTimer(void*, const union _LARGE_INTEGER*, long, void(*)(void*, unsigned long, unsigned long), void*, int); + _c_LINKC unsigned long WaitForSingleObject(void*, unsigned long); + _c_LINKC int CloseHandle(void*); + + static inline long long cco_utime(void) { + static const long long epoch_offset = 11644473600000000LL; /* microseconds betweeen Jan 1,1601 - Jan 1,1970 */ + unsigned long long quad; /* 64-bit value, 100-nanosecond intervals since January 1, 1601 00:00 UTC */ + GetSystemTimePreciseAsFileTime((struct _FILETIME*)&quad); + return (long long)quad/10 - epoch_offset; /* microseconds since epoch */ } + + static inline void cco_usleep(long long usec) { + unsigned long long ft = -10*usec; + void* timer = CreateWaitableTimerW(NULL, true, NULL); + SetWaitableTimer(timer, (const union _LARGE_INTEGER*)&ft, 0, NULL, NULL, 0); + WaitForSingleObject(timer, ~0UL); + CloseHandle(timer); + } #else #include <sys/time.h> - static inline void cco_sleep(long msec) { - struct timeval tv = {.tv_sec=msec/1000, .tv_usec=1000*(msec % 1000)}; + static inline long long cco_utime(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec*1000000LL + tv.tv_usec; + } + + static inline void cco_usleep(long long usec) { + struct timeval tv = {.tv_sec=(time_t)(usec/1000000), .tv_usec=(suseconds_t)(usec % 1000000)}; select(0, NULL, NULL, NULL, &tv); } #endif -static inline void cco_timer_start(cco_timer* tm, long msec) { - tm->interval = msec*(CLOCKS_PER_SEC/1000); - tm->start = clock(); +typedef struct { long long interval, start; } cco_timer; + +#define cco_timer_await(...) c_MACRO_OVERLOAD(cco_timer_await, __VA_ARGS__) +#define cco_timer_await_2(tm, usec) cco_timer_await_3(tm, usec, ) +#define cco_timer_await_3(tm, usec, ret) \ + do { \ + cco_timer_start(tm, usec); \ + cco_await_2(cco_timer_expired(tm), ret); \ + } while (0) + +static inline void cco_timer_start(cco_timer* tm, long long usec) { + tm->interval = usec; + tm->start = cco_utime(); } -static inline cco_timer cco_timer_from(long msec) { - cco_timer tm = {msec*(CLOCKS_PER_SEC/1000), clock()}; +static inline cco_timer cco_timer_from(long long usec) { + cco_timer tm = {.interval=usec, .start=cco_utime()}; return tm; } static inline void cco_timer_restart(cco_timer* tm) { - tm->start = clock(); + tm->start = cco_utime(); } static inline bool cco_timer_expired(cco_timer* tm) { - return clock() - tm->start >= tm->interval; + return cco_utime() - tm->start >= tm->interval; } -static inline long cco_timer_remaining(cco_timer* tm) { - return (long)((double)(tm->start + tm->interval - clock())*(1000.0/CLOCKS_PER_SEC)); +static inline long long cco_timer_remaining(cco_timer* tm) { + return tm->start + tm->interval - cco_utime(); } #endif |
