diff options
| author | Nic Gaffney <gaffney_nic@protonmail.com> | 2024-06-12 21:15:52 -0500 |
|---|---|---|
| committer | Nic Gaffney <gaffney_nic@protonmail.com> | 2024-06-12 21:15:52 -0500 |
| commit | 963fae202108acd0498349e872e4811fa6c6aba0 (patch) | |
| tree | 1a7d5b6ee837700819d8f6f5a2484342a0ab6ec1 /vendor/zgui/libs/winpthreads/src/misc.c | |
| parent | 6084001df845815efd9c0eb712acf4fd9311ce36 (diff) | |
| download | particle-sim-963fae202108acd0498349e872e4811fa6c6aba0.tar.gz | |
Added imgui for configuration
Diffstat (limited to 'vendor/zgui/libs/winpthreads/src/misc.c')
| -rw-r--r-- | vendor/zgui/libs/winpthreads/src/misc.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/vendor/zgui/libs/winpthreads/src/misc.c b/vendor/zgui/libs/winpthreads/src/misc.c new file mode 100644 index 0000000..457bc86 --- /dev/null +++ b/vendor/zgui/libs/winpthreads/src/misc.c @@ -0,0 +1,197 @@ +/* + Copyright (c) 2011-2016 mingw-w64 project + + 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 <windows.h> +#include "pthread.h" +#include "misc.h" + +void (WINAPI *_pthread_get_system_time_best_as_file_time) (LPFILETIME) = NULL; +static ULONGLONG (WINAPI *_pthread_get_tick_count_64) (VOID); + +#if defined(__GNUC__) || defined(__clang__) +__attribute__((constructor)) +#endif +static void winpthreads_init(void) +{ + HMODULE mod = GetModuleHandleA("kernel32.dll"); + if (mod) + { + _pthread_get_tick_count_64 = + (ULONGLONG (WINAPI *)(VOID))(void*) GetProcAddress(mod, "GetTickCount64"); + + /* <1us precision on Windows 10 */ + _pthread_get_system_time_best_as_file_time = + (void (WINAPI *)(LPFILETIME))(void*) GetProcAddress(mod, "GetSystemTimePreciseAsFileTime"); + } + + if (!_pthread_get_system_time_best_as_file_time) + /* >15ms precision on Windows 10 */ + _pthread_get_system_time_best_as_file_time = GetSystemTimeAsFileTime; +} + +#if defined(_MSC_VER) && !defined(__clang__) +/* Force a reference to __xc_t to prevent whole program optimization + * from discarding the variable. */ + +/* On x86, symbols are prefixed with an underscore. */ +# if defined(_M_IX86) +# pragma comment(linker, "/include:___xc_t") +# else +# pragma comment(linker, "/include:__xc_t") +# endif + +#pragma section(".CRT$XCT", long, read) +__declspec(allocate(".CRT$XCT")) +extern const _PVFV __xc_t; +const _PVFV __xc_t = winpthreads_init; +#endif + +unsigned long long _pthread_time_in_ms(void) +{ + FILETIME ft; + + GetSystemTimeAsFileTime(&ft); + return (((unsigned long long)ft.dwHighDateTime << 32) + ft.dwLowDateTime + - 0x19DB1DED53E8000ULL) / 10000ULL; +} + +unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts) +{ + unsigned long long t = (unsigned long long) ts->tv_sec * 1000LL; + /* The +999999 is here to ensure that the division always rounds up */ + t += (unsigned long long) (ts->tv_nsec + 999999) / 1000000; + + return t; +} + +unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts) +{ + unsigned long long t1 = _pthread_time_in_ms_from_timespec(ts); + unsigned long long t2 = _pthread_time_in_ms(); + + /* Prevent underflow */ + if (t1 < t2) return 0; + return t1 - t2; +} + +static unsigned long long +_pthread_get_tick_count (long long *frequency) +{ + if (_pthread_get_tick_count_64 != NULL) + return _pthread_get_tick_count_64 (); + + LARGE_INTEGER freq, timestamp; + + if (*frequency == 0) + { + if (QueryPerformanceFrequency (&freq)) + *frequency = freq.QuadPart; + else + *frequency = -1; + } + + if (*frequency > 0 && QueryPerformanceCounter (×tamp)) + return timestamp.QuadPart / (*frequency / 1000); + + /* Fallback */ + return GetTickCount (); +} + +/* A wrapper around WaitForSingleObject() that ensures that + * the wait function does not time out before the time + * actually runs out. This is needed because WaitForSingleObject() + * might have poor accuracy, returning earlier than expected. + * On the other hand, returning a bit *later* than expected + * is acceptable in a preemptive multitasking environment. + */ +unsigned long +_pthread_wait_for_single_object (void *handle, unsigned long timeout) +{ + DWORD result; + unsigned long long start_time, end_time; + unsigned long wait_time; + long long frequency = 0; + + if (timeout == INFINITE || timeout == 0) + return WaitForSingleObject ((HANDLE) handle, (DWORD) timeout); + + start_time = _pthread_get_tick_count (&frequency); + end_time = start_time + timeout; + wait_time = timeout; + + do + { + unsigned long long current_time; + + result = WaitForSingleObject ((HANDLE) handle, (DWORD) wait_time); + if (result != WAIT_TIMEOUT) + break; + + current_time = _pthread_get_tick_count (&frequency); + if (current_time >= end_time) + break; + + wait_time = (DWORD) (end_time - current_time); + } while (TRUE); + + return result; +} + +/* A wrapper around WaitForMultipleObjects() that ensures that + * the wait function does not time out before the time + * actually runs out. This is needed because WaitForMultipleObjects() + * might have poor accuracy, returning earlier than expected. + * On the other hand, returning a bit *later* than expected + * is acceptable in a preemptive multitasking environment. + */ +unsigned long +_pthread_wait_for_multiple_objects (unsigned long count, void **handles, unsigned int all, unsigned long timeout) +{ + DWORD result; + unsigned long long start_time, end_time; + unsigned long wait_time; + long long frequency = 0; + + if (timeout == INFINITE || timeout == 0) + return WaitForMultipleObjects ((DWORD) count, (HANDLE *) handles, all, (DWORD) timeout); + + start_time = _pthread_get_tick_count (&frequency); + end_time = start_time + timeout; + wait_time = timeout; + + do + { + unsigned long long current_time; + + result = WaitForMultipleObjects ((DWORD) count, (HANDLE *) handles, all, (DWORD) wait_time); + if (result != WAIT_TIMEOUT) + break; + + current_time = _pthread_get_tick_count (&frequency); + if (current_time >= end_time) + break; + + wait_time = (DWORD) (end_time - current_time); + } while (TRUE); + + return result; +} |
