Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
darkk committed Aug 29, 2024
1 parent 85de1c3 commit ce4c6c1
Showing 1 changed file with 21 additions and 22 deletions.
43 changes: 21 additions & 22 deletions Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,7 @@ void SetThreadAffinity ( std::thread &t, int cpu );
#endif
void SetAffinity ( int cpu );

// That's not UINT64_MAX as it's converted to int64_t sometimes.
constexpr uint64_t timer_inf = INT64_MAX;

__inline__ uint64_t timer_sub(uint64_t a, uint64_t b)
{
#if defined(__mips__)
// Tune SafeMHzFor32CC to reflect max clock freq. of your machine with 32-bit cycle counter.
const uint32_t SafeMHzFor32CC = 1500;
if ((a >> 60) != (b >> 60)) return timer_inf;
const uint32_t scale = (a >> 60) + 1;
const uint32_t acc = a & UINT32_MAX, bcc = b & UINT32_MAX;
uint32_t as = (a >> 32) & (UINT32_MAX >> 4), bs = (b >> 32) & (UINT32_MAX >> 4);
if (as < bs) as += 1 << 28; // 28-bit seconds value overflows every 8 years, so wrap is safe
const uint32_t dsceil = as - bs + 1;
const uint32_t safeds = UINT32_MAX / 1000000 * scale / SafeMHzFor32CC; // that's floor()
if (dsceil > safeds) return timer_inf; // 32-bit CC value wraps every ~two seconds @ 2 GHz
const uint32_t diff = acc - bcc; // well-defined unsigned overflow
return uint64_t(diff) * scale;
#else
return (a > b) ? a - b : timer_inf; // true 64-bit cycle counter overflows once a century @ 4 GHz
#endif
}
#define timer_inf INT64_MAX // That's not UINT64_MAX as it's converted to int64_t sometimes.

#ifndef __x86_64__
#if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64)
Expand Down Expand Up @@ -307,6 +286,26 @@ __inline__ bool timer_counts_ns ( void )

#endif // !defined(_MSC_VER)

__inline__ uint64_t timer_sub(uint64_t a, uint64_t b)
{
#if defined(__mips__)
// Tune SafeMHzFor32CC to reflect max clock freq. of your machine with 32-bit cycle counter.
const uint32_t SafeMHzFor32CC = 1500;
if ((a >> 60) != (b >> 60)) return timer_inf;
const uint32_t scale = (a >> 60) + 1;
const uint32_t acc = a & UINT32_MAX, bcc = b & UINT32_MAX;
uint32_t as = (a >> 32) & (UINT32_MAX >> 4), bs = (b >> 32) & (UINT32_MAX >> 4);
if (as < bs) as += 1 << 28; // 28-bit seconds value overflows every 8 years, so wrap is safe
const uint32_t dsceil = as - bs + 1;
const uint32_t safeds = UINT32_MAX / 1000000 * scale / SafeMHzFor32CC; // that's floor()
if (dsceil > safeds) return timer_inf; // 32-bit CC value wraps every ~two seconds @ 2 GHz
const uint32_t diff = acc - bcc; // well-defined unsigned overflow
return uint64_t(diff) * scale;
#else
return (a > b) ? a - b : timer_inf; // true 64-bit cycle counter overflows once a century @ 4 GHz
#endif
}

//-----------------------------------------------------------------------------

#ifndef __WORDSIZE
Expand Down

0 comments on commit ce4c6c1

Please sign in to comment.