Question

I have found a function to get milliseconds since the Mac was started:

U32 Platform::getRealMilliseconds()
{
   // Duration is a S32 value.
   // if negative, it is in microseconds.
   // if positive, it is in milliseconds.
   Duration durTime = AbsoluteToDuration(UpTime());
   U32 ret;
   if( durTime < 0 )
      ret = durTime / -1000;
   else 
      ret = durTime;

   return ret;
}

The problem is that after ~20 days AbsoluteToDuration returns INT_MAX all the time until the Mac is rebooted.

I have tried to use method below, it worked, but looks like gettimeofday takes more time and slows down the game a bit:

timeval tim;
gettimeofday(&tim, NULL);
U32 ret = ((tim.tv_sec) * 1000 + tim.tv_usec/1000.0) + 0.5;

Is there a better way to get number of milliseconds elapsed since some epoch (preferably since the app started)?

Thanks!

Was it helpful?

Solution

Your real problem is that you are trying to fit an uptime-in-milliseconds value into a 32-bit integer. If you do that your value will always wrap back to zero (or saturate) in 49 days or less, no matter how you obtain the value.

One possible solution would be to track time values with a 64-bit integer instead; that way the day of reckoning gets postponed for a few hundred years and so you don't have to worry about the problem. Here's a MacOS/X implementation of that:

uint64_t GetTimeInMillisecondsSinceBoot()
{
   return UnsignedWideToUInt64(AbsoluteToNanoseconds(UpTime()))/1000000;
}

... or if you don't want to return a 64-bit time value, the next-best thing would be to record the current time-in-milliseconds value when your program starts, and then always subtract that value from the values you return. That way things won't break until your own program has been running for at least 49 days, which I suppose is unlikely for a game.

uint32_t GetTimeInMillisecondsSinceProgramStart()
{
   static uint64_t _firstTimeMillis = GetTimeInMillisecondsSinceBoot();
   uint64_t nowMillis = GetTimeInMillisecondsSinceBoot();
   return (uint32_t) (nowMillis-_firstTimeMillis);
}

OTHER TIPS

My preferred method is mach_absolute_time - see this tech note - I use the second method, i.e. mach_absolute_time to get time stamps and mach_timebase_info to get the constants needed to convert the difference between time stamps into an actual time value (with nanosecond resolution).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top