< prev index next >

src/hotspot/os/aix/os_aix.cpp

Print this page




1067 // this unconditionally, so we do it.
1068 //
1069 // See: https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.basetrf2/read_real_time.htm
1070 //
1071 // On PASE: mread_real_time will always return RTC_POWER_PC data, so no
1072 // conversion is necessary. However, mread_real_time will not return
1073 // monotonic results but merely matches read_real_time. So we need a tweak
1074 // to ensure monotonic results.
1075 //
1076 // For PASE no public documentation exists, just word by IBM
1077 jlong os::javaTimeNanos() {
1078   timebasestruct_t time;
1079   int rc = mread_real_time(&time, TIMEBASE_SZ);
1080   if (os::Aix::on_pase()) {
1081     assert(rc == RTC_POWER, "expected time format RTC_POWER from mread_real_time in PASE");
1082     jlong now = jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);
1083     jlong prev = max_real_time;
1084     if (now <= prev) {
1085       return prev;   // same or retrograde time;
1086     }
1087     jlong obsv = Atomic::cmpxchg(now, &max_real_time, prev);
1088     assert(obsv >= prev, "invariant");   // Monotonicity
1089     // If the CAS succeeded then we're done and return "now".
1090     // If the CAS failed and the observed value "obsv" is >= now then
1091     // we should return "obsv".  If the CAS failed and now > obsv > prv then
1092     // some other thread raced this thread and installed a new value, in which case
1093     // we could either (a) retry the entire operation, (b) retry trying to install now
1094     // or (c) just return obsv.  We use (c).   No loop is required although in some cases
1095     // we might discard a higher "now" value in deference to a slightly lower but freshly
1096     // installed obsv value.   That's entirely benign -- it admits no new orderings compared
1097     // to (a) or (b) -- and greatly reduces coherence traffic.
1098     // We might also condition (c) on the magnitude of the delta between obsv and now.
1099     // Avoiding excessive CAS operations to hot RW locations is critical.
1100     // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
1101     return (prev == obsv) ? now : obsv;
1102   } else {
1103     if (rc != RTC_POWER) {
1104       rc = time_base_to_time(&time, TIMEBASE_SZ);
1105       assert(rc != -1, "error calling time_base_to_time()");
1106     }
1107     return jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);


1777   }
1778 }
1779 
1780 static void jdk_misc_signal_init() {
1781   // Initialize signal structures
1782   ::memset((void*)pending_signals, 0, sizeof(pending_signals));
1783 
1784   // Initialize signal semaphore
1785   local_sem_init();
1786 }
1787 
1788 void os::signal_notify(int sig) {
1789   Atomic::inc(&pending_signals[sig]);
1790   local_sem_post();
1791 }
1792 
1793 static int check_pending_signals() {
1794   for (;;) {
1795     for (int i = 0; i < NSIG + 1; i++) {
1796       jint n = pending_signals[i];
1797       if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
1798         return i;
1799       }
1800     }
1801     JavaThread *thread = JavaThread::current();
1802     ThreadBlockInVM tbivm(thread);
1803 
1804     bool threadIsSuspended;
1805     do {
1806       thread->set_suspend_equivalent();
1807       // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
1808 
1809       local_sem_wait();
1810 
1811       // were we externally suspended while we were waiting?
1812       threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
1813       if (threadIsSuspended) {
1814         //
1815         // The semaphore has been incremented, but while we were waiting
1816         // another thread suspended us. We don't want to continue running
1817         // while suspended because that would surprise the thread that




1067 // this unconditionally, so we do it.
1068 //
1069 // See: https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.basetrf2/read_real_time.htm
1070 //
1071 // On PASE: mread_real_time will always return RTC_POWER_PC data, so no
1072 // conversion is necessary. However, mread_real_time will not return
1073 // monotonic results but merely matches read_real_time. So we need a tweak
1074 // to ensure monotonic results.
1075 //
1076 // For PASE no public documentation exists, just word by IBM
1077 jlong os::javaTimeNanos() {
1078   timebasestruct_t time;
1079   int rc = mread_real_time(&time, TIMEBASE_SZ);
1080   if (os::Aix::on_pase()) {
1081     assert(rc == RTC_POWER, "expected time format RTC_POWER from mread_real_time in PASE");
1082     jlong now = jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);
1083     jlong prev = max_real_time;
1084     if (now <= prev) {
1085       return prev;   // same or retrograde time;
1086     }
1087     jlong obsv = Atomic::cmpxchg(&max_real_time, prev, now);
1088     assert(obsv >= prev, "invariant");   // Monotonicity
1089     // If the CAS succeeded then we're done and return "now".
1090     // If the CAS failed and the observed value "obsv" is >= now then
1091     // we should return "obsv".  If the CAS failed and now > obsv > prv then
1092     // some other thread raced this thread and installed a new value, in which case
1093     // we could either (a) retry the entire operation, (b) retry trying to install now
1094     // or (c) just return obsv.  We use (c).   No loop is required although in some cases
1095     // we might discard a higher "now" value in deference to a slightly lower but freshly
1096     // installed obsv value.   That's entirely benign -- it admits no new orderings compared
1097     // to (a) or (b) -- and greatly reduces coherence traffic.
1098     // We might also condition (c) on the magnitude of the delta between obsv and now.
1099     // Avoiding excessive CAS operations to hot RW locations is critical.
1100     // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate
1101     return (prev == obsv) ? now : obsv;
1102   } else {
1103     if (rc != RTC_POWER) {
1104       rc = time_base_to_time(&time, TIMEBASE_SZ);
1105       assert(rc != -1, "error calling time_base_to_time()");
1106     }
1107     return jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);


1777   }
1778 }
1779 
1780 static void jdk_misc_signal_init() {
1781   // Initialize signal structures
1782   ::memset((void*)pending_signals, 0, sizeof(pending_signals));
1783 
1784   // Initialize signal semaphore
1785   local_sem_init();
1786 }
1787 
1788 void os::signal_notify(int sig) {
1789   Atomic::inc(&pending_signals[sig]);
1790   local_sem_post();
1791 }
1792 
1793 static int check_pending_signals() {
1794   for (;;) {
1795     for (int i = 0; i < NSIG + 1; i++) {
1796       jint n = pending_signals[i];
1797       if (n > 0 && n == Atomic::cmpxchg(&pending_signals[i], n, n - 1)) {
1798         return i;
1799       }
1800     }
1801     JavaThread *thread = JavaThread::current();
1802     ThreadBlockInVM tbivm(thread);
1803 
1804     bool threadIsSuspended;
1805     do {
1806       thread->set_suspend_equivalent();
1807       // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
1808 
1809       local_sem_wait();
1810 
1811       // were we externally suspended while we were waiting?
1812       threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
1813       if (threadIsSuspended) {
1814         //
1815         // The semaphore has been incremented, but while we were waiting
1816         // another thread suspended us. We don't want to continue running
1817         // while suspended because that would surprise the thread that


< prev index next >