Print this page
rev 2869 : 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
Summary: Replaces calls to os::javaTimeMillis(), which does not guarantee montonicity, in GC code to os::javaTimeNanos() with a suitable conversion factor. os::javaTimeNanos() mostly guarantees montonicity depending on the underlying OS implementation and, as a result, a better alternative. Changes in OS files are to make use of the newly defined constants in globalDefinitions.hpp.
Reviewed-by:

Split Close
Expand all
Collapse all
          --- old/src/os/solaris/vm/os_solaris.cpp
          +++ new/src/os/solaris/vm/os_solaris.cpp
↓ open down ↓ 1666 lines elided ↑ open up ↑
1667 1667  // This function could be called before TLS is initialized, for example, when
1668 1668  // VM receives an async signal or when VM causes a fatal error during
1669 1669  // initialization. Return NULL if thr_getspecific() fails.
1670 1670  void* os::thread_local_storage_at(int index) {
1671 1671    // %%% this is used only in threadLocalStorage.cpp
1672 1672    void* r = NULL;
1673 1673    return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
1674 1674  }
1675 1675  
1676 1676  
1677      -const int NANOSECS_PER_MILLISECS = 1000000;
1678 1677  // gethrtime can move backwards if read from one cpu and then a different cpu
1679 1678  // getTimeNanos is guaranteed to not move backward on Solaris
1680 1679  // local spinloop created as faster for a CAS on an int than
1681 1680  // a CAS on a 64bit jlong. Also Atomic::cmpxchg for jlong is not
1682 1681  // supported on sparc v8 or pre supports_cx8 intel boxes.
1683 1682  // oldgetTimeNanos for systems which do not support CAS on 64bit jlong
1684 1683  // i.e. sparc v8 and pre supports_cx8 (i486) intel boxes
1685 1684  inline hrtime_t oldgetTimeNanos() {
1686 1685    int gotlock = LOCK_INVALID;
1687 1686    hrtime_t newtime = gethrtime();
↓ open down ↓ 108 lines elided ↑ open up ↑
1796 1795  }
1797 1796  
1798 1797  double os::elapsedVTime() {
1799 1798    return (double)gethrvtime() / (double)hrtime_hz;
1800 1799  }
1801 1800  
1802 1801  // Used internally for comparisons only
1803 1802  // getTimeMillis guaranteed to not move backwards on Solaris
1804 1803  jlong getTimeMillis() {
1805 1804    jlong nanotime = getTimeNanos();
1806      -  return (jlong)(nanotime / NANOSECS_PER_MILLISECS);
     1805 +  return (jlong)(nanotime / NANOSECS_PER_MILLISEC);
1807 1806  }
1808 1807  
1809 1808  // Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
1810 1809  jlong os::javaTimeMillis() {
1811 1810    timeval t;
1812 1811    if (gettimeofday( &t, NULL) == -1)
1813 1812      fatal(err_msg("os::javaTimeMillis: gettimeofday (%s)", strerror(errno)));
1814 1813    return jlong(t.tv_sec) * 1000  +  jlong(t.tv_usec) / 1000;
1815 1814  }
1816 1815  
↓ open down ↓ 4240 lines elided ↑ open up ↑
6057 6056   * The solaris and linux implementations of park/unpark are fairly
6058 6057   * conservative for now, but can be improved. They currently use a
6059 6058   * mutex/condvar pair, plus _counter.
6060 6059   * Park decrements _counter if > 0, else does a condvar wait.  Unpark
6061 6060   * sets count to 1 and signals condvar.  Only one thread ever waits
6062 6061   * on the condvar. Contention seen when trying to park implies that someone
6063 6062   * is unparking you, so don't wait. And spurious returns are fine, so there
6064 6063   * is no need to track notifications.
6065 6064   */
6066 6065  
6067      -#define NANOSECS_PER_SEC 1000000000
6068      -#define NANOSECS_PER_MILLISEC 1000000
6069 6066  #define MAX_SECS 100000000
6070      -
6071 6067  /*
6072 6068   * This code is common to linux and solaris and will be moved to a
6073 6069   * common place in dolphin.
6074 6070   *
6075 6071   * The passed in time value is either a relative time in nanoseconds
6076 6072   * or an absolute time in milliseconds. Either way it has to be unpacked
6077 6073   * into suitable seconds and nanoseconds components and stored in the
6078 6074   * given timespec structure.
6079 6075   * Given time is a 64-bit value and the time_t used in the timespec is only
6080 6076   * a signed-32-bit value (except on 64-bit Linux) we have to watch for
↓ open down ↓ 396 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX