summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/mfluadir/otfcc/src/stopwatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/mfluadir/otfcc/src/stopwatch.c')
-rw-r--r--Build/source/texk/web2c/mfluadir/otfcc/src/stopwatch.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/mfluadir/otfcc/src/stopwatch.c b/Build/source/texk/web2c/mfluadir/otfcc/src/stopwatch.c
new file mode 100644
index 00000000000..bbb775ee482
--- /dev/null
+++ b/Build/source/texk/web2c/mfluadir/otfcc/src/stopwatch.c
@@ -0,0 +1,108 @@
+#include "stopwatch.h"
+#ifdef _WIN32
+LARGE_INTEGER getFILETIMEoffset(void);
+
+LARGE_INTEGER getFILETIMEoffset() {
+ SYSTEMTIME s;
+ FILETIME f;
+ LARGE_INTEGER t;
+
+ s.wYear = 1970;
+ s.wMonth = 1;
+ s.wDay = 1;
+ s.wHour = 0;
+ s.wMinute = 0;
+ s.wSecond = 0;
+ s.wMilliseconds = 0;
+ SystemTimeToFileTime(&s, &f);
+ t.QuadPart = f.dwHighDateTime;
+ t.QuadPart <<= 32;
+ t.QuadPart |= f.dwLowDateTime;
+ return (t);
+}
+
+void time_now(struct timespec *tv) {
+ LARGE_INTEGER t;
+ FILETIME f;
+ double microseconds;
+ static LARGE_INTEGER offset;
+ static double frequencyToMicroseconds;
+ static int initialized = 0;
+ static BOOL usePerformanceCounter = 0;
+
+ if (!initialized) {
+ LARGE_INTEGER performanceFrequency;
+ initialized = 1;
+ usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
+ if (usePerformanceCounter) {
+ QueryPerformanceCounter(&offset);
+ frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.0;
+ } else {
+ offset = getFILETIMEoffset();
+ frequencyToMicroseconds = 10.0;
+ }
+ }
+ if (usePerformanceCounter)
+ QueryPerformanceCounter(&t);
+ else {
+ GetSystemTimeAsFileTime(&f);
+ t.QuadPart = f.dwHighDateTime;
+ t.QuadPart <<= 32;
+ t.QuadPart |= f.dwLowDateTime;
+ }
+
+ t.QuadPart -= offset.QuadPart;
+ microseconds = (double)t.QuadPart / frequencyToMicroseconds;
+ t.QuadPart = microseconds;
+ tv->tv_sec = t.QuadPart / 1000000;
+ tv->tv_nsec = t.QuadPart % 1000000 * 1000;
+}
+#elif __MACH__
+#define ORWL_NANO (+1.0E-9)
+#define ORWL_GIGA UINT64_C(1000000000)
+
+static double orwl_timebase = 0.0;
+static uint64_t orwl_timestart = 0;
+
+void time_now(struct timespec *tv) {
+ // be more careful in a multithreaded environement
+ if (!orwl_timestart) {
+ mach_timebase_info_data_t tb = {0};
+ mach_timebase_info(&tb);
+ orwl_timebase = tb.numer;
+ orwl_timebase /= tb.denom;
+ orwl_timestart = mach_absolute_time();
+ }
+ double diff = (mach_absolute_time() - orwl_timestart) * orwl_timebase;
+ tv->tv_sec = diff * ORWL_NANO;
+ tv->tv_nsec = diff - (tv->tv_sec * ORWL_GIGA);
+}
+#else
+void time_now(struct timespec *tv) {
+ clock_gettime(CLOCK_REALTIME, tv);
+}
+#endif
+
+#define BILLION 1000000000
+
+static void timespec_diff(struct timespec *start, struct timespec *stop, struct timespec *result) {
+ if ((stop->tv_nsec - start->tv_nsec) < 0) {
+ result->tv_sec = stop->tv_sec - start->tv_sec - 1;
+ result->tv_nsec = stop->tv_nsec - start->tv_nsec + BILLION;
+ } else {
+ result->tv_sec = stop->tv_sec - start->tv_sec;
+ result->tv_nsec = stop->tv_nsec - start->tv_nsec;
+ }
+
+ return;
+}
+
+sds push_stopwatch(struct timespec *sofar) {
+ struct timespec ends;
+ time_now(&ends);
+ struct timespec diff;
+ timespec_diff(sofar, &ends, &diff);
+ *sofar = ends;
+ sds log = sdscatprintf(sdsempty(), "Step time = %gs.\n", diff.tv_sec + diff.tv_nsec / (double)BILLION);
+ return log;
+}