No more timer callback after 553 seconds on ppc macs


#1

Hi Jules,

There is a bug with the HiResCounterHandler on powerpc macs. On these, the mach_timebase_info returns
numerator=1000000000, denominator=33330633 * 1000000 . These values are very large, so in the code

(mach_absolute_time() * numerator) / denominator) for the millisecond counter, there is an overflow that occurs every 553 seconds ((655366553665536*65536) / (33330633 MHz * 1000000000)). Each time this overflow happens, the millisecondcounter jumps back in time and the juce demo app stops receiving timer callbacks.

(on intel macs , numerator=1 , denominator=1000000)

I suggest to use something like (push the overflow to 553000000 seconds in the future, which is quite far away I think)

if ((timebase.numer < 1000000000) { numerator = timebase.numer; denominator = timebase.denom * (int64) 1000000; } else { numerator = timebase.numer / 1000000; denominator = timebase.denom; }

or anything nicer that prevents the overflow


#2

That’s nasty! It’s also stupid - why the hell would they choose

numerator=1000000000, denominator=33330633 * 1000000

…instead of

numerator=1000, denominator=33330633, which amounts to the same thing?!

Perhaps a better fix would be to find the greatest common divisor of the numerator and denominator, and divide both by that number? (Although I’m amazed that the OS wouldn’t already have done that!)


#3

well to be honest, you are the one multiplying 33330633 by 1000000 (to convert from nanosec to millisec) :).


#4

Ah, sorry, I thought you were quoting the numbers that were returned by the system! Ok, your suggestion makes a lot of sense then!


#5

How about this?

if (timebase.numer % 1000000 == 0) { numerator = timebase.numer / 1000000; denominator = timebase.denom; } else { numerator = timebase.numer; denominator = timebase.denom * (int64) 1000000; }


#6

ah, that’s what I wrote in the first place but I thought you would found it too ugly :slight_smile: It’s fine for me of course