summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2023-06-05 19:02:03 +0200
committerTyge Løvset <[email protected]>2023-06-05 19:13:22 +0200
commit4b8f8d2a97ca1411ad6dccdeac6195574edac852 (patch)
treec744f00c4288d3e8988a07b417c754ca5db17f4a /include
parent2d3250d2d35dda415840d8403b7b8957ca40914a (diff)
downloadSTC-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.h79
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