aboutsummaryrefslogtreecommitdiff
path: root/sokol_time.h
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2017-11-28 18:49:20 +0100
committerAndre Weissflog <floooh@gmail.com>2017-11-28 18:49:20 +0100
commit282109e100ee9778c9b120c6754aee87c4e778c9 (patch)
treeb418108274af887710494407a6732290670b0683 /sokol_time.h
parent9146bcaa43c91c99c7c77c0b2739f4c48a1c29bf (diff)
new header: sokol_time.h
Diffstat (limited to 'sokol_time.h')
-rw-r--r--sokol_time.h191
1 files changed, 191 insertions, 0 deletions
diff --git a/sokol_time.h b/sokol_time.h
new file mode 100644
index 00000000..dda47f0e
--- /dev/null
+++ b/sokol_time.h
@@ -0,0 +1,191 @@
+#pragma once
+/*
+ sokol_time.h -- simple cross-platform time measurement
+
+ Do this:
+ #define SOKOL_IMPL
+ before you include this file in *one* C or C++ file to create the
+ implementation.
+
+ Optionally provide the following defines with your own implementations:
+ SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
+
+ void stm_setup();
+ Call once before any other functions to initialize sokol_time
+ (this calls for instance QueryPerformanceFrequency on Windows)
+
+ uint64_t stm_now();
+ Get current point in time in unspecified ticks. The value that
+ is returned has no relation to some absolute time or time unit,
+ it is only useful to compute time differences.
+
+ uint64_t stm_diff(uint64_t new, uint64_t old);
+ Computes the time difference between new and old. This will always
+ return a positive, non-zero value.
+
+ uint64_t stm_since(uint64_t start);
+ Takes the current time, and returns the elapsed time since start
+ (this is a shortcut for "stm_diff(stm_now(), start)")
+
+ uint64_t stm_laptime(uint64_t* last_time);
+ Takes the current time, returns the time since last_time,
+ and stores current time in last_time. If last_time is 0, the
+ return value will be 0!
+
+ double stm_sec(uint64_t ticks);
+ double stm_ms(uint64_t ticks);
+ double stm_us(uint64_t ticks);
+ double stm_ns(uint64_t ticks);
+ Convert a tick value into seconds, milliseconds, microseconds
+ or nanoseconds. Note that not all platforms will have nanosecond
+ or even microsecond precision.
+
+ Use the following time measurement functions:
+
+ Windows: QueryPerformanceFrequency() / QueryPerformanceCounter()
+ MacOS/iOS: mach_absolute_time()
+ emscripten: clock_gettime(CLOCK_MONOTONIC)
+ Linux+others: clock_gettime(CLOCK_MONITONIC)
+
+
+ MIT License
+
+ Copyright (c) 2017 Andre Weissflog
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void stm_setup();
+extern uint64_t stm_now();
+extern uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks);
+extern uint64_t stm_since(uint64_t start_ticks);
+extern uint64_t stm_laptime(uint64_t* last_time);
+extern double stm_sec(uint64_t ticks);
+extern double stm_ms(uint64_t ticks);
+extern double stm_us(uint64_t ticks);
+extern double stm_ns(uint64_t ticks);
+
+/*-- IMPLEMENTATION ----------------------------------------------------------*/
+#ifdef SOKOL_IMPL
+#ifndef SOKOL_ASSERT
+ #include <assert.h>
+ #define SOKOL_ASSERT(c) assert(c)
+#endif
+
+static int _stm_initialized;
+#if defined(_WIN32)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+LARGE_INTEGER _stm_win_freq;
+LARGE_INTEGER _stm_win_start;
+#elif defined(__APPLE__) && defined(__MACH__)
+#include <mach/mach_time.h>
+mach_timebase_info_data_t _stm_osx_timebase;
+uint64_t _stm_osx_start;
+#else /* anything else, this will need more care for non-Linux platforms */
+#include <time.h>
+uint64_t _stm_posix_start;
+#endif
+
+void stm_setup() {
+ SOKOL_ASSERT(0 == _stm_initialized);
+ _stm_initialized = 1;
+ #if defined(_WIN32)
+ QueryPerformanceFrequency(&_stm_win_freq);
+ QueryPerformanceCounter(&_stm_win_start);
+ #elif defined(__APPLE__) && defined(__MACH__)
+ mach_timebase_info(&_stm_osx_timebase);
+ _stm_osx_start = mach_absolute_time();
+ #else
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ _stm_posix_start = (uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec;
+ #endif
+}
+
+uint64_t stm_now() {
+ SOKOL_ASSERT(_stm_initialized);
+ uint64_t now;
+ #if defined(_WIN32)
+ LARGE_INTEGER qpc_t;
+ QueryPerformanceCounter(&qpc_t);
+ now = ((qpc_t.QuadPart - _stm_win_start.QuadPart) * 1000000000) / _stm_win_freq.QuadPart;
+ return
+ #elif defined(__APPLE__) && defined(__MACH__)
+ now = mach_absolute_time() - _stm_osx_start;
+ #else
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ now = ((uint64_t)ts.tv_sec*1000000000 + (uint64_t)ts.tv_nsec) - _stm_posix_start;
+ #endif
+ return now;
+}
+
+uint64_t stm_diff(uint64_t new_ticks, uint64_t old_ticks) {
+ if (new_ticks > old_ticks) {
+ return new_ticks - old_ticks;
+ }
+ else {
+ /* FIXME: this should be a value that converts to a non-null double */
+ return 1;
+ }
+}
+
+uint64_t stm_since(uint64_t start_ticks) {
+ return stm_diff(stm_now(), start_ticks);
+}
+
+uint64_t stm_laptime(uint64_t* last_time) {
+ SOKOL_ASSERT(last_time);
+ uint64_t dt = 0;
+ uint64_t now = stm_now();
+ if (0 != *last_time) {
+ dt = stm_diff(now, *last_time);
+ }
+ *last_time = now;
+ return dt;
+}
+
+double stm_sec(uint64_t ticks) {
+ return (double)ticks / 1000000000.0;
+}
+
+double stm_ms(uint64_t ticks) {
+ return (double)ticks / 1000000.0;
+}
+
+double stm_us(uint64_t ticks) {
+ return (double)ticks / 1000.0;
+}
+
+double stm_ns(uint64_t ticks) {
+ return (double)ticks;
+}
+#endif /* SOKOL_IMPL */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif