src/os/solaris/vm/os_solaris.cpp

changeset 6667
917873d2983d
parent 6556
6048424d3865
child 6782
f73af4455d7d
child 6911
ce8f6bb717c9
equal deleted inserted replaced
6666:a062c3691003 6667:917873d2983d
413 return Solaris::physical_memory(); 413 return Solaris::physical_memory();
414 } 414 }
415 415
416 static hrtime_t first_hrtime = 0; 416 static hrtime_t first_hrtime = 0;
417 static const hrtime_t hrtime_hz = 1000*1000*1000; 417 static const hrtime_t hrtime_hz = 1000*1000*1000;
418 const int LOCK_BUSY = 1;
419 const int LOCK_FREE = 0;
420 const int LOCK_INVALID = -1;
421 static volatile hrtime_t max_hrtime = 0; 418 static volatile hrtime_t max_hrtime = 0;
422 static volatile int max_hrtime_lock = LOCK_FREE; // Update counter with LSB as lock-in-progress
423 419
424 420
425 void os::Solaris::initialize_system_info() { 421 void os::Solaris::initialize_system_info() {
426 set_processor_count(sysconf(_SC_NPROCESSORS_CONF)); 422 set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
427 _processors_online = sysconf (_SC_NPROCESSORS_ONLN); 423 _processors_online = sysconf (_SC_NPROCESSORS_ONLN);
1532 void* r = NULL; 1528 void* r = NULL;
1533 return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r; 1529 return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
1534 } 1530 }
1535 1531
1536 1532
1537 // gethrtime can move backwards if read from one cpu and then a different cpu 1533 // gethrtime() should be monotonic according to the documentation,
1538 // getTimeNanos is guaranteed to not move backward on Solaris 1534 // but some virtualized platforms are known to break this guarantee.
1539 // local spinloop created as faster for a CAS on an int than 1535 // getTimeNanos() must be guaranteed not to move backwards, so we
1540 // a CAS on a 64bit jlong. Also Atomic::cmpxchg for jlong is not 1536 // are forced to add a check here.
1541 // supported on sparc v8 or pre supports_cx8 intel boxes.
1542 // oldgetTimeNanos for systems which do not support CAS on 64bit jlong
1543 // i.e. sparc v8 and pre supports_cx8 (i486) intel boxes
1544 inline hrtime_t oldgetTimeNanos() {
1545 int gotlock = LOCK_INVALID;
1546 hrtime_t newtime = gethrtime();
1547
1548 for (;;) {
1549 // grab lock for max_hrtime
1550 int curlock = max_hrtime_lock;
1551 if (curlock & LOCK_BUSY) continue;
1552 if (gotlock = Atomic::cmpxchg(LOCK_BUSY, &max_hrtime_lock, LOCK_FREE) != LOCK_FREE) continue;
1553 if (newtime > max_hrtime) {
1554 max_hrtime = newtime;
1555 } else {
1556 newtime = max_hrtime;
1557 }
1558 // release lock
1559 max_hrtime_lock = LOCK_FREE;
1560 return newtime;
1561 }
1562 }
1563 // gethrtime can move backwards if read from one cpu and then a different cpu
1564 // getTimeNanos is guaranteed to not move backward on Solaris
1565 inline hrtime_t getTimeNanos() { 1537 inline hrtime_t getTimeNanos() {
1566 if (VM_Version::supports_cx8()) { 1538 const hrtime_t now = gethrtime();
1567 const hrtime_t now = gethrtime(); 1539 const hrtime_t prev = max_hrtime;
1568 // Use atomic long load since 32-bit x86 uses 2 registers to keep long. 1540 if (now <= prev) {
1569 const hrtime_t prev = Atomic::load((volatile jlong*)&max_hrtime); 1541 return prev; // same or retrograde time;
1570 if (now <= prev) return prev; // same or retrograde time; 1542 }
1571 const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev); 1543 const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev);
1572 assert(obsv >= prev, "invariant"); // Monotonicity 1544 assert(obsv >= prev, "invariant"); // Monotonicity
1573 // If the CAS succeeded then we're done and return "now". 1545 // If the CAS succeeded then we're done and return "now".
1574 // If the CAS failed and the observed value "obs" is >= now then 1546 // If the CAS failed and the observed value "obsv" is >= now then
1575 // we should return "obs". If the CAS failed and now > obs > prv then 1547 // we should return "obsv". If the CAS failed and now > obsv > prv then
1576 // some other thread raced this thread and installed a new value, in which case 1548 // some other thread raced this thread and installed a new value, in which case
1577 // we could either (a) retry the entire operation, (b) retry trying to install now 1549 // we could either (a) retry the entire operation, (b) retry trying to install now
1578 // or (c) just return obs. We use (c). No loop is required although in some cases 1550 // or (c) just return obsv. We use (c). No loop is required although in some cases
1579 // we might discard a higher "now" value in deference to a slightly lower but freshly 1551 // we might discard a higher "now" value in deference to a slightly lower but freshly
1580 // installed obs value. That's entirely benign -- it admits no new orderings compared 1552 // installed obsv value. That's entirely benign -- it admits no new orderings compared
1581 // to (a) or (b) -- and greatly reduces coherence traffic. 1553 // to (a) or (b) -- and greatly reduces coherence traffic.
1582 // We might also condition (c) on the magnitude of the delta between obs and now. 1554 // We might also condition (c) on the magnitude of the delta between obsv and now.
1583 // Avoiding excessive CAS operations to hot RW locations is critical. 1555 // Avoiding excessive CAS operations to hot RW locations is critical.
1584 // See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate 1556 // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
1585 return (prev == obsv) ? now : obsv ; 1557 return (prev == obsv) ? now : obsv;
1586 } else {
1587 return oldgetTimeNanos();
1588 }
1589 } 1558 }
1590 1559
1591 // Time since start-up in seconds to a fine granularity. 1560 // Time since start-up in seconds to a fine granularity.
1592 // Used by VMSelfDestructTimer and the MemProfiler. 1561 // Used by VMSelfDestructTimer and the MemProfiler.
1593 double os::elapsedTime() { 1562 double os::elapsedTime() {

mercurial