src/os/bsd/vm/os_bsd.cpp

changeset 6782
f73af4455d7d
parent 6779
364b73402247
parent 6680
78bbf4d43a14
child 6876
710a3c8b516e
child 6918
d22136881b85
     1.1 --- a/src/os/bsd/vm/os_bsd.cpp	Wed May 28 12:07:21 2014 -0700
     1.2 +++ b/src/os/bsd/vm/os_bsd.cpp	Thu May 29 09:56:06 2014 -0700
     1.3 @@ -123,12 +123,19 @@
     1.4  #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
     1.5  
     1.6  #define LARGEPAGES_BIT (1 << 6)
     1.7 +
     1.8 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
     1.9 +
    1.10  ////////////////////////////////////////////////////////////////////////////////
    1.11  // global variables
    1.12  julong os::Bsd::_physical_memory = 0;
    1.13  
    1.14 -
    1.15 +#ifdef __APPLE__
    1.16 +mach_timebase_info_data_t os::Bsd::_timebase_info = {0, 0};
    1.17 +volatile uint64_t         os::Bsd::_max_abstime   = 0;
    1.18 +#else
    1.19  int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;
    1.20 +#endif
    1.21  pthread_t os::Bsd::_main_thread;
    1.22  int os::Bsd::_page_size = -1;
    1.23  
    1.24 @@ -986,13 +993,15 @@
    1.25    return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
    1.26  }
    1.27  
    1.28 +#ifndef __APPLE__
    1.29  #ifndef CLOCK_MONOTONIC
    1.30  #define CLOCK_MONOTONIC (1)
    1.31  #endif
    1.32 +#endif
    1.33  
    1.34  #ifdef __APPLE__
    1.35  void os::Bsd::clock_init() {
    1.36 -        // XXXDARWIN: Investigate replacement monotonic clock
    1.37 +  mach_timebase_info(&_timebase_info);
    1.38  }
    1.39  #else
    1.40  void os::Bsd::clock_init() {
    1.41 @@ -1007,10 +1016,38 @@
    1.42  #endif
    1.43  
    1.44  
    1.45 +#ifdef __APPLE__
    1.46 +
    1.47 +jlong os::javaTimeNanos() {
    1.48 +    const uint64_t tm = mach_absolute_time();
    1.49 +    const uint64_t now = (tm * Bsd::_timebase_info.numer) / Bsd::_timebase_info.denom;
    1.50 +    const uint64_t prev = Bsd::_max_abstime;
    1.51 +    if (now <= prev) {
    1.52 +      return prev;   // same or retrograde time;
    1.53 +    }
    1.54 +    const uint64_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&Bsd::_max_abstime, prev);
    1.55 +    assert(obsv >= prev, "invariant");   // Monotonicity
    1.56 +    // If the CAS succeeded then we're done and return "now".
    1.57 +    // If the CAS failed and the observed value "obsv" is >= now then
    1.58 +    // we should return "obsv".  If the CAS failed and now > obsv > prv then
    1.59 +    // some other thread raced this thread and installed a new value, in which case
    1.60 +    // we could either (a) retry the entire operation, (b) retry trying to install now
    1.61 +    // or (c) just return obsv.  We use (c).   No loop is required although in some cases
    1.62 +    // we might discard a higher "now" value in deference to a slightly lower but freshly
    1.63 +    // installed obsv value.   That's entirely benign -- it admits no new orderings compared
    1.64 +    // to (a) or (b) -- and greatly reduces coherence traffic.
    1.65 +    // We might also condition (c) on the magnitude of the delta between obsv and now.
    1.66 +    // Avoiding excessive CAS operations to hot RW locations is critical.
    1.67 +    // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
    1.68 +    return (prev == obsv) ? now : obsv;
    1.69 +}
    1.70 +
    1.71 +#else // __APPLE__
    1.72 +
    1.73  jlong os::javaTimeNanos() {
    1.74    if (Bsd::supports_monotonic_clock()) {
    1.75      struct timespec tp;
    1.76 -    int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp);
    1.77 +    int status = Bsd::_clock_gettime(CLOCK_MONOTONIC, &tp);
    1.78      assert(status == 0, "gettime error");
    1.79      jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
    1.80      return result;
    1.81 @@ -1023,6 +1060,8 @@
    1.82    }
    1.83  }
    1.84  
    1.85 +#endif // __APPLE__
    1.86 +
    1.87  void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
    1.88    if (Bsd::supports_monotonic_clock()) {
    1.89      info_ptr->max_value = ALL_64_BITS;
    1.90 @@ -2351,7 +2390,6 @@
    1.91                          (!FLAG_IS_DEFAULT(UseLargePages) ||
    1.92                           !FLAG_IS_DEFAULT(LargePageSizeInBytes)
    1.93                          );
    1.94 -  char msg[128];
    1.95  
    1.96    // Create a large shared memory region to attach to based on size.
    1.97    // Currently, size is the total size of the heap
    1.98 @@ -2372,8 +2410,7 @@
    1.99       //            coalesce into large pages. Try to reserve large pages when
   1.100       //            the system is still "fresh".
   1.101       if (warn_on_failure) {
   1.102 -       jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
   1.103 -       warning(msg);
   1.104 +       warning("Failed to reserve shared memory (errno = %d).", errno);
   1.105       }
   1.106       return NULL;
   1.107    }
   1.108 @@ -2390,8 +2427,7 @@
   1.109  
   1.110    if ((intptr_t)addr == -1) {
   1.111       if (warn_on_failure) {
   1.112 -       jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
   1.113 -       warning(msg);
   1.114 +       warning("Failed to attach shared memory (errno = %d).", err);
   1.115       }
   1.116       return NULL;
   1.117    }
   1.118 @@ -3890,6 +3926,7 @@
   1.119    return true;
   1.120  }
   1.121  
   1.122 +ATTRIBUTE_PRINTF(3, 0)
   1.123  int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) {
   1.124    return ::vsnprintf(buf, count, format, args);
   1.125  }

mercurial