< prev index next >

src/os/solaris/vm/os_solaris.cpp

Print this page
rev 13069 : imported patch ClearFPUAtPark


5086 
5087 void os::PlatformEvent::park() {           // AKA: down()
5088   // Transitions for _Event:
5089   //   -1 => -1 : illegal
5090   //    1 =>  0 : pass - return immediately
5091   //    0 => -1 : block; then set _Event to 0 before returning
5092 
5093   // Invariant: Only the thread associated with the Event/PlatformEvent
5094   // may call park().
5095   assert(_nParked == 0, "invariant");
5096 
5097   int v;
5098   for (;;) {
5099     v = _Event;
5100     if (Atomic::cmpxchg(v-1, &_Event, v) == v) break;
5101   }
5102   guarantee(v >= 0, "invariant");
5103   if (v == 0) {
5104     // Do this the hard way by blocking ...
5105     // See http://monaco.sfbay/detail.jsf?cr=5094058.
5106     // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking.
5107     // Only for SPARC >= V8PlusA
5108 #if defined(__sparc) && defined(COMPILER2)
5109     if (ClearFPUAtPark) { _mark_fpu_nosave(); }
5110 #endif
5111     int status = os::Solaris::mutex_lock(_mutex);
5112     assert_status(status == 0, status, "mutex_lock");
5113     guarantee(_nParked == 0, "invariant");
5114     ++_nParked;
5115     while (_Event < 0) {
5116       // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
5117       // Treat this the same as if the wait was interrupted
5118       // With usr/lib/lwp going to kernel, always handle ETIME
5119       status = os::Solaris::cond_wait(_cond, _mutex);
5120       if (status == ETIME) status = EINTR;
5121       assert_status(status == 0 || status == EINTR, status, "cond_wait");
5122     }
5123     --_nParked;
5124     _Event = 0;
5125     status = os::Solaris::mutex_unlock(_mutex);
5126     assert_status(status == 0, status, "mutex_unlock");
5127     // Paranoia to ensure our locked and lock-free paths interact
5128     // correctly with each other.
5129     OrderAccess::fence();
5130   }


5133 int os::PlatformEvent::park(jlong millis) {
5134   // Transitions for _Event:
5135   //   -1 => -1 : illegal
5136   //    1 =>  0 : pass - return immediately
5137   //    0 => -1 : block; then set _Event to 0 before returning
5138 
5139   guarantee(_nParked == 0, "invariant");
5140   int v;
5141   for (;;) {
5142     v = _Event;
5143     if (Atomic::cmpxchg(v-1, &_Event, v) == v) break;
5144   }
5145   guarantee(v >= 0, "invariant");
5146   if (v != 0) return OS_OK;
5147 
5148   int ret = OS_TIMEOUT;
5149   timestruc_t abst;
5150   compute_abstime(&abst, millis);
5151 
5152   // See http://monaco.sfbay/detail.jsf?cr=5094058.
5153   // For Solaris SPARC set fprs.FEF=0 prior to parking.
5154   // Only for SPARC >= V8PlusA
5155 #if defined(__sparc) && defined(COMPILER2)
5156   if (ClearFPUAtPark) { _mark_fpu_nosave(); }
5157 #endif
5158   int status = os::Solaris::mutex_lock(_mutex);
5159   assert_status(status == 0, status, "mutex_lock");
5160   guarantee(_nParked == 0, "invariant");
5161   ++_nParked;
5162   while (_Event < 0) {
5163     int status = os::Solaris::cond_timedwait(_cond, _mutex, &abst);
5164     assert_status(status == 0 || status == EINTR ||
5165                   status == ETIME || status == ETIMEDOUT,
5166                   status, "cond_timedwait");
5167     if (!FilterSpuriousWakeups) break;                // previous semantics
5168     if (status == ETIME || status == ETIMEDOUT) break;
5169     // We consume and ignore EINTR and spurious wakeups.
5170   }
5171   --_nParked;
5172   if (_Event >= 0) ret = OS_OK;
5173   _Event = 0;
5174   status = os::Solaris::mutex_unlock(_mutex);
5175   assert_status(status == 0, status, "mutex_unlock");
5176   // Paranoia to ensure our locked and lock-free paths interact
5177   // correctly with each other.


5330   }
5331 
5332   int status;
5333 
5334   if (_counter > 0)  { // no wait needed
5335     _counter = 0;
5336     status = os::Solaris::mutex_unlock(_mutex);
5337     assert(status == 0, "invariant");
5338     // Paranoia to ensure our locked and lock-free paths interact
5339     // correctly with each other and Java-level accesses.
5340     OrderAccess::fence();
5341     return;
5342   }
5343 
5344   OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
5345   jt->set_suspend_equivalent();
5346   // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
5347 
5348   // Do this the hard way by blocking ...
5349   // See http://monaco.sfbay/detail.jsf?cr=5094058.
5350   // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking.
5351   // Only for SPARC >= V8PlusA
5352 #if defined(__sparc) && defined(COMPILER2)
5353   if (ClearFPUAtPark) { _mark_fpu_nosave(); }
5354 #endif
5355 
5356   if (time == 0) {
5357     status = os::Solaris::cond_wait(_cond, _mutex);
5358   } else {
5359     status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime);
5360   }
5361   // Note that an untimed cond_wait() can sometimes return ETIME on older
5362   // versions of the Solaris.
5363   assert_status(status == 0 || status == EINTR ||
5364                 status == ETIME || status == ETIMEDOUT,
5365                 status, "cond_timedwait");
5366 
5367   _counter = 0;
5368   status = os::Solaris::mutex_unlock(_mutex);
5369   assert_status(status == 0, status, "mutex_unlock");
5370   // Paranoia to ensure our locked and lock-free paths interact
5371   // correctly with each other and Java-level accesses.
5372   OrderAccess::fence();
5373 
5374   // If externally suspended while waiting, re-suspend
5375   if (jt->handle_special_suspend_equivalent_condition()) {




5086 
5087 void os::PlatformEvent::park() {           // AKA: down()
5088   // Transitions for _Event:
5089   //   -1 => -1 : illegal
5090   //    1 =>  0 : pass - return immediately
5091   //    0 => -1 : block; then set _Event to 0 before returning
5092 
5093   // Invariant: Only the thread associated with the Event/PlatformEvent
5094   // may call park().
5095   assert(_nParked == 0, "invariant");
5096 
5097   int v;
5098   for (;;) {
5099     v = _Event;
5100     if (Atomic::cmpxchg(v-1, &_Event, v) == v) break;
5101   }
5102   guarantee(v >= 0, "invariant");
5103   if (v == 0) {
5104     // Do this the hard way by blocking ...
5105     // See http://monaco.sfbay/detail.jsf?cr=5094058.





5106     int status = os::Solaris::mutex_lock(_mutex);
5107     assert_status(status == 0, status, "mutex_lock");
5108     guarantee(_nParked == 0, "invariant");
5109     ++_nParked;
5110     while (_Event < 0) {
5111       // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
5112       // Treat this the same as if the wait was interrupted
5113       // With usr/lib/lwp going to kernel, always handle ETIME
5114       status = os::Solaris::cond_wait(_cond, _mutex);
5115       if (status == ETIME) status = EINTR;
5116       assert_status(status == 0 || status == EINTR, status, "cond_wait");
5117     }
5118     --_nParked;
5119     _Event = 0;
5120     status = os::Solaris::mutex_unlock(_mutex);
5121     assert_status(status == 0, status, "mutex_unlock");
5122     // Paranoia to ensure our locked and lock-free paths interact
5123     // correctly with each other.
5124     OrderAccess::fence();
5125   }


5128 int os::PlatformEvent::park(jlong millis) {
5129   // Transitions for _Event:
5130   //   -1 => -1 : illegal
5131   //    1 =>  0 : pass - return immediately
5132   //    0 => -1 : block; then set _Event to 0 before returning
5133 
5134   guarantee(_nParked == 0, "invariant");
5135   int v;
5136   for (;;) {
5137     v = _Event;
5138     if (Atomic::cmpxchg(v-1, &_Event, v) == v) break;
5139   }
5140   guarantee(v >= 0, "invariant");
5141   if (v != 0) return OS_OK;
5142 
5143   int ret = OS_TIMEOUT;
5144   timestruc_t abst;
5145   compute_abstime(&abst, millis);
5146 
5147   // See http://monaco.sfbay/detail.jsf?cr=5094058.





5148   int status = os::Solaris::mutex_lock(_mutex);
5149   assert_status(status == 0, status, "mutex_lock");
5150   guarantee(_nParked == 0, "invariant");
5151   ++_nParked;
5152   while (_Event < 0) {
5153     int status = os::Solaris::cond_timedwait(_cond, _mutex, &abst);
5154     assert_status(status == 0 || status == EINTR ||
5155                   status == ETIME || status == ETIMEDOUT,
5156                   status, "cond_timedwait");
5157     if (!FilterSpuriousWakeups) break;                // previous semantics
5158     if (status == ETIME || status == ETIMEDOUT) break;
5159     // We consume and ignore EINTR and spurious wakeups.
5160   }
5161   --_nParked;
5162   if (_Event >= 0) ret = OS_OK;
5163   _Event = 0;
5164   status = os::Solaris::mutex_unlock(_mutex);
5165   assert_status(status == 0, status, "mutex_unlock");
5166   // Paranoia to ensure our locked and lock-free paths interact
5167   // correctly with each other.


5320   }
5321 
5322   int status;
5323 
5324   if (_counter > 0)  { // no wait needed
5325     _counter = 0;
5326     status = os::Solaris::mutex_unlock(_mutex);
5327     assert(status == 0, "invariant");
5328     // Paranoia to ensure our locked and lock-free paths interact
5329     // correctly with each other and Java-level accesses.
5330     OrderAccess::fence();
5331     return;
5332   }
5333 
5334   OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
5335   jt->set_suspend_equivalent();
5336   // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
5337 
5338   // Do this the hard way by blocking ...
5339   // See http://monaco.sfbay/detail.jsf?cr=5094058.






5340   if (time == 0) {
5341     status = os::Solaris::cond_wait(_cond, _mutex);
5342   } else {
5343     status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime);
5344   }
5345   // Note that an untimed cond_wait() can sometimes return ETIME on older
5346   // versions of the Solaris.
5347   assert_status(status == 0 || status == EINTR ||
5348                 status == ETIME || status == ETIMEDOUT,
5349                 status, "cond_timedwait");
5350 
5351   _counter = 0;
5352   status = os::Solaris::mutex_unlock(_mutex);
5353   assert_status(status == 0, status, "mutex_unlock");
5354   // Paranoia to ensure our locked and lock-free paths interact
5355   // correctly with each other and Java-level accesses.
5356   OrderAccess::fence();
5357 
5358   // If externally suspended while waiting, re-suspend
5359   if (jt->handle_special_suspend_equivalent_condition()) {


< prev index next >