Mercurial > hg > truffle
comparison src/os/solaris/vm/os_solaris.cpp @ 499:8a25d96bcf08
6784100: getTimeNanos - CAS reduction
Summary: Get rid of the CAS loop in getTimeNanos to reduce coherence traffic on Solaris.
Reviewed-by: acorn, kvn, ysr
author | xlu |
---|---|
date | Fri, 19 Dec 2008 14:40:28 -0800 |
parents | 24fda36852ce |
children | 773234c55e8c |
comparison
equal
deleted
inserted
replaced
498:c6065343356f | 499:8a25d96bcf08 |
---|---|
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 |