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()) {
|