Line data Source code
1 : #ifdef __PLUMED_HAS_ASMJIT 2 : // This file is part of AsmJit project <https://asmjit.com> 3 : // 4 : // See asmjit.h or LICENSE.md for license and copyright information 5 : // SPDX-License-Identifier: Zlib 6 : 7 : #include "api-build_p.h" 8 : #include "osutils.h" 9 : #include "support.h" 10 : 11 : #if defined(_WIN32) 12 : #include <atomic> 13 : #elif defined(__APPLE__) 14 : #include <mach/mach_time.h> 15 : #else 16 : #include <time.h> 17 : #include <unistd.h> 18 : #endif 19 : 20 : ASMJIT_BEGIN_NAMESPACE 21 : 22 0 : uint32_t OSUtils::getTickCount() noexcept { 23 : #if defined(_WIN32) 24 : enum HiResStatus : uint32_t { 25 : kHiResUnknown = 0, 26 : kHiResAvailable = 1, 27 : kHiResNotAvailable = 2 28 : }; 29 : 30 : static std::atomic<uint32_t> _hiResStatus(kHiResUnknown); 31 : static volatile double _hiResFreq(0); 32 : 33 : uint32_t status = _hiResStatus.load(); 34 : LARGE_INTEGER now, qpf; 35 : 36 : if (status != kHiResNotAvailable && ::QueryPerformanceCounter(&now)) { 37 : double freq = _hiResFreq; 38 : if (status == kHiResUnknown) { 39 : // Detects the availability of high resolution counter. 40 : if (::QueryPerformanceFrequency(&qpf)) { 41 : freq = double(qpf.QuadPart) / 1000.0; 42 : _hiResFreq = freq; 43 : _hiResStatus.compare_exchange_strong(status, kHiResAvailable); 44 : status = kHiResAvailable; 45 : } 46 : else { 47 : // High resolution not available. 48 : _hiResStatus.compare_exchange_strong(status, kHiResNotAvailable); 49 : } 50 : } 51 : 52 : if (status == kHiResAvailable) 53 : return uint32_t(uint64_t(int64_t(double(now.QuadPart) / freq)) & 0xFFFFFFFFu); 54 : } 55 : 56 : // Bail to `GetTickCount()` if we cannot use high resolution. 57 : return ::GetTickCount(); 58 : #elif defined(__APPLE__) 59 : // See Apple's QA1398. 60 : static mach_timebase_info_data_t _machTime; 61 : 62 : uint32_t denom = _machTime.denom; 63 : if (ASMJIT_UNLIKELY(!denom)) { 64 : if (mach_timebase_info(&_machTime) != KERN_SUCCESS || !(denom = _machTime.denom)) 65 : return 0; 66 : } 67 : 68 : // `mach_absolute_time()` returns nanoseconds, we want milliseconds. 69 : uint64_t t = mach_absolute_time() / 1000000u; 70 : t = (t * _machTime.numer) / _machTime.denom; 71 : return uint32_t(t & 0xFFFFFFFFu); 72 : #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 73 : struct timespec ts; 74 0 : if (ASMJIT_UNLIKELY(clock_gettime(CLOCK_MONOTONIC, &ts) != 0)) 75 : return 0; 76 : 77 0 : uint64_t t = (uint64_t(ts.tv_sec ) * 1000u) + (uint64_t(ts.tv_nsec) / 1000000u); 78 0 : return uint32_t(t & 0xFFFFFFFFu); 79 : #else 80 : #pragma message("asmjit::OSUtils::getTickCount() doesn't have implementation for the target OS.") 81 : return 0; 82 : #endif 83 : } 84 : 85 : ASMJIT_END_NAMESPACE 86 : 87 : #endif // __PLUMED_HAS_ASMJIT