4116 "Could not open pause file '%s', continuing immediately.\n", filename); |
4116 "Could not open pause file '%s', continuing immediately.\n", filename); |
4117 } |
4117 } |
4118 } |
4118 } |
4119 |
4119 |
4120 |
4120 |
4121 // Refer to the comments in os_solaris.cpp park-unpark. |
4121 // Refer to the comments in os_solaris.cpp park-unpark. The next two |
|
4122 // comment paragraphs are worth repeating here: |
|
4123 // |
|
4124 // Assumption: |
|
4125 // Only one parker can exist on an event, which is why we allocate |
|
4126 // them per-thread. Multiple unparkers can coexist. |
|
4127 // |
|
4128 // _Event serves as a restricted-range semaphore. |
|
4129 // -1 : thread is blocked, i.e. there is a waiter |
|
4130 // 0 : neutral: thread is running or ready, |
|
4131 // could have been signaled after a wait started |
|
4132 // 1 : signaled - thread is running or ready |
4122 // |
4133 // |
4123 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can |
4134 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can |
4124 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable. |
4135 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable. |
4125 // For specifics regarding the bug see GLIBC BUGID 261237 : |
4136 // For specifics regarding the bug see GLIBC BUGID 261237 : |
4126 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html. |
4137 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html. |
4201 abstime->tv_nsec = usec * 1000; |
4212 abstime->tv_nsec = usec * 1000; |
4202 return abstime; |
4213 return abstime; |
4203 } |
4214 } |
4204 |
4215 |
4205 void os::PlatformEvent::park() { // AKA "down()" |
4216 void os::PlatformEvent::park() { // AKA "down()" |
|
4217 // Transitions for _Event: |
|
4218 // -1 => -1 : illegal |
|
4219 // 1 => 0 : pass - return immediately |
|
4220 // 0 => -1 : block; then set _Event to 0 before returning |
|
4221 |
4206 // Invariant: Only the thread associated with the Event/PlatformEvent |
4222 // Invariant: Only the thread associated with the Event/PlatformEvent |
4207 // may call park(). |
4223 // may call park(). |
4208 // TODO: assert that _Assoc != NULL or _Assoc == Self |
4224 // TODO: assert that _Assoc != NULL or _Assoc == Self |
4209 assert(_nParked == 0, "invariant"); |
4225 assert(_nParked == 0, "invariant"); |
4210 |
4226 |
4238 } |
4254 } |
4239 guarantee(_Event >= 0, "invariant"); |
4255 guarantee(_Event >= 0, "invariant"); |
4240 } |
4256 } |
4241 |
4257 |
4242 int os::PlatformEvent::park(jlong millis) { |
4258 int os::PlatformEvent::park(jlong millis) { |
|
4259 // Transitions for _Event: |
|
4260 // -1 => -1 : illegal |
|
4261 // 1 => 0 : pass - return immediately |
|
4262 // 0 => -1 : block; then set _Event to 0 before returning |
|
4263 |
4243 guarantee(_nParked == 0, "invariant"); |
4264 guarantee(_nParked == 0, "invariant"); |
4244 |
4265 |
4245 int v; |
4266 int v; |
4246 for (;;) { |
4267 for (;;) { |
4247 v = _Event; |
4268 v = _Event; |
4301 return ret; |
4322 return ret; |
4302 } |
4323 } |
4303 |
4324 |
4304 void os::PlatformEvent::unpark() { |
4325 void os::PlatformEvent::unpark() { |
4305 // Transitions for _Event: |
4326 // Transitions for _Event: |
4306 // 0 :=> 1 |
4327 // 0 => 1 : just return |
4307 // 1 :=> 1 |
4328 // 1 => 1 : just return |
4308 // -1 :=> either 0 or 1; must signal target thread |
4329 // -1 => either 0 or 1; must signal target thread |
4309 // That is, we can safely transition _Event from -1 to either |
4330 // That is, we can safely transition _Event from -1 to either |
4310 // 0 or 1. |
4331 // 0 or 1. |
4311 // See also: "Semaphores in Plan 9" by Mullender & Cox |
4332 // See also: "Semaphores in Plan 9" by Mullender & Cox |
4312 // |
4333 // |
4313 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
4334 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
4314 // that it will take two back-to-back park() calls for the owning |
4335 // that it will take two back-to-back park() calls for the owning |
4315 // thread to block. This has the benefit of forcing a spurious return |
4336 // thread to block. This has the benefit of forcing a spurious return |
4328 pthread_cond_signal(_cond); |
4349 pthread_cond_signal(_cond); |
4329 } |
4350 } |
4330 status = pthread_mutex_unlock(_mutex); |
4351 status = pthread_mutex_unlock(_mutex); |
4331 assert_status(status == 0, status, "mutex_unlock"); |
4352 assert_status(status == 0, status, "mutex_unlock"); |
4332 if (AnyWaiters != 0) { |
4353 if (AnyWaiters != 0) { |
|
4354 // Note that we signal() *after* dropping the lock for "immortal" Events. |
|
4355 // This is safe and avoids a common class of futile wakeups. In rare |
|
4356 // circumstances this can cause a thread to return prematurely from |
|
4357 // cond_{timed}wait() but the spurious wakeup is benign and the victim |
|
4358 // will simply re-test the condition and re-park itself. |
|
4359 // This provides particular benefit if the underlying platform does not |
|
4360 // provide wait morphing. |
4333 status = pthread_cond_signal(_cond); |
4361 status = pthread_cond_signal(_cond); |
4334 assert_status(status == 0, status, "cond_signal"); |
4362 assert_status(status == 0, status, "cond_signal"); |
4335 } |
4363 } |
4336 |
|
4337 // Note that we signal() _after dropping the lock for "immortal" Events. |
|
4338 // This is safe and avoids a common class of futile wakeups. In rare |
|
4339 // circumstances this can cause a thread to return prematurely from |
|
4340 // cond_{timed}wait() but the spurious wakeup is benign and the victim will |
|
4341 // simply re-test the condition and re-park itself. |
|
4342 } |
4364 } |
4343 |
4365 |
4344 |
4366 |
4345 // JSR166 |
4367 // JSR166 |
4346 // ------------------------------------------------------- |
4368 // ------------------------------------------------------- |