title: Platform specific MONOTONIC clock problems
body: <p>I am porting <a href="https://github.com/victorfisac/Physac/blob/master/src/physac.h" rel="nofollow noreferrer">this C library</a> to Rust  </p>
  
  <p>It has a sort of timer logic:  </p>
  
  <pre class="lang-c prettyprint-override"><code>PHYSACDEF void InitTimer(void)
  {
      #if defined(_WIN32)
          QueryPerformanceFrequency((unsigned long long int *) &amp;frequency);
      #endif
  
      #if defined(__linux__)
          struct timespec now;
          if (clock_gettime(CLOCK_MONOTONIC, &amp;now) == 0)
              frequency = 1000000000;
      #endif
  
      #if defined(__APPLE__)
          mach_timebase_info_data_t timebase;
          mach_timebase_info(&amp;timebase);
          frequency = (timebase.denom*1e9)/timebase.numer;
      #endif
  
      baseTime = GetTimeCount();      // Get MONOTONIC clock time offset
      startTime = GetCurrentTime();   // Get current time
  }
  </code></pre>
  
  <p>This function seems to be initializing 3 timer variables: <code>baseTime</code>, <code>startTime</code>, <code>frequency</code>.<br>
  For windows the code is clear, for the <code>__APPLE__</code> platform it does something that makes sense too, but for linux it is just checking if <code>clok_gettime(...)</code> doesn't fail and setting frequency to 1000000000.</p>
  
  <p>Next let's look at GetTimeCount():  </p>
  
  <pre class="lang-c prettyprint-override"><code>static uint64_t GetTimeCount(void)
  {
      uint64_t value = 0;
  
      #if defined(_WIN32)
          QueryPerformanceCounter((unsigned long long int *) &amp;value);
      #endif
  
      #if defined(__linux__)
          struct timespec now;
          clock_gettime(CLOCK_MONOTONIC, &amp;now);
          value = (uint64_t)now.tv_sec*(uint64_t)1000000000 + (uint64_t)now.tv_nsec;
      #endif
  
      #if defined(__APPLE__)
          value = mach_absolute_time();
      #endif
  
      return value;
  }
  </code></pre>
  
  <p>Yet again, it does something that makes sense on windows and macos, but for linux it multiplies <code>now.tv_sec</code> with the <code>1000000000</code> value, converting the value into nanoseconds.</p>
  
  <p>And now, GetCurrentTime():</p>
  
  <pre class="lang-c prettyprint-override"><code>static double GetCurrentTime(void)
  {
      return (double)(GetTimeCount() - baseTime)/frequency*1000;
  }
  </code></pre>
  
  <p>Makes enough sense at a first glance, but frequency is initialized with 0 when declared so if the operation on linux fails, it will crash because there will be a division by zero (at least that's what i think).
  [EDIT]: The operation on linux can't fail, since MONOTONIC_CLOCK can't fail. It is the time since boot, so it can't fail.</p>
  
  <p>Does Rust provide a tool that looks like the MacOS or windows solution so i can use it to initialize those values instead?
  Can i use <code>std::time::Instant</code> to replace the variables or should i use it in another way?
  If there is no Rust universal tool, should i do platform specific code:</p>
  
  <pre class="lang-rust prettyprint-override"><code>#[cfg(target_os = "windows")]
  // winapi crate code here
  </code></pre>