1636 } |
1636 } |
1637 // gethrtime can move backwards if read from one cpu and then a different cpu |
1637 // gethrtime can move backwards if read from one cpu and then a different cpu |
1638 // getTimeNanos is guaranteed to not move backward on Solaris |
1638 // getTimeNanos is guaranteed to not move backward on Solaris |
1639 inline hrtime_t getTimeNanos() { |
1639 inline hrtime_t getTimeNanos() { |
1640 if (VM_Version::supports_cx8()) { |
1640 if (VM_Version::supports_cx8()) { |
1641 bool retry = false; |
1641 const hrtime_t now = gethrtime(); |
1642 hrtime_t newtime = gethrtime(); |
1642 const hrtime_t prev = max_hrtime; |
1643 hrtime_t oldmaxtime = max_hrtime; |
1643 if (now <= prev) return prev; // same or retrograde time; |
1644 hrtime_t retmaxtime = oldmaxtime; |
1644 const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev); |
1645 while ((newtime > retmaxtime) && (retry == false || retmaxtime != oldmaxtime)) { |
1645 assert(obsv >= prev, "invariant"); // Monotonicity |
1646 oldmaxtime = retmaxtime; |
1646 // If the CAS succeeded then we're done and return "now". |
1647 retmaxtime = Atomic::cmpxchg(newtime, (volatile jlong *)&max_hrtime, oldmaxtime); |
1647 // If the CAS failed and the observed value "obs" is >= now then |
1648 retry = true; |
1648 // we should return "obs". If the CAS failed and now > obs > prv then |
1649 } |
1649 // some other thread raced this thread and installed a new value, in which case |
1650 return (newtime > retmaxtime) ? newtime : retmaxtime; |
1650 // we could either (a) retry the entire operation, (b) retry trying to install now |
|
1651 // or (c) just return obs. We use (c). No loop is required although in some cases |
|
1652 // we might discard a higher "now" value in deference to a slightly lower but freshly |
|
1653 // installed obs value. That's entirely benign -- it admits no new orderings compared |
|
1654 // to (a) or (b) -- and greatly reduces coherence traffic. |
|
1655 // We might also condition (c) on the magnitude of the delta between obs and now. |
|
1656 // Avoiding excessive CAS operations to hot RW locations is critical. |
|
1657 // See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate |
|
1658 return (prev == obsv) ? now : obsv ; |
1651 } else { |
1659 } else { |
1652 return oldgetTimeNanos(); |
1660 return oldgetTimeNanos(); |
1653 } |
1661 } |
1654 } |
1662 } |
1655 |
1663 |