5413 "Could not open pause file '%s', continuing immediately.\n", filename); |
5413 "Could not open pause file '%s', continuing immediately.\n", filename); |
5414 } |
5414 } |
5415 } |
5415 } |
5416 |
5416 |
5417 |
5417 |
5418 // Refer to the comments in os_solaris.cpp park-unpark. |
5418 // Refer to the comments in os_solaris.cpp park-unpark. The next two |
|
5419 // comment paragraphs are worth repeating here: |
|
5420 // |
|
5421 // Assumption: |
|
5422 // Only one parker can exist on an event, which is why we allocate |
|
5423 // them per-thread. Multiple unparkers can coexist. |
|
5424 // |
|
5425 // _Event serves as a restricted-range semaphore. |
|
5426 // -1 : thread is blocked, i.e. there is a waiter |
|
5427 // 0 : neutral: thread is running or ready, |
|
5428 // could have been signaled after a wait started |
|
5429 // 1 : signaled - thread is running or ready |
5419 // |
5430 // |
5420 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can |
5431 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can |
5421 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable. |
5432 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable. |
5422 // For specifics regarding the bug see GLIBC BUGID 261237 : |
5433 // For specifics regarding the bug see GLIBC BUGID 261237 : |
5423 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html. |
5434 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html. |
5512 } |
5523 } |
5513 return abstime; |
5524 return abstime; |
5514 } |
5525 } |
5515 |
5526 |
5516 void os::PlatformEvent::park() { // AKA "down()" |
5527 void os::PlatformEvent::park() { // AKA "down()" |
|
5528 // Transitions for _Event: |
|
5529 // -1 => -1 : illegal |
|
5530 // 1 => 0 : pass - return immediately |
|
5531 // 0 => -1 : block; then set _Event to 0 before returning |
|
5532 |
5517 // Invariant: Only the thread associated with the Event/PlatformEvent |
5533 // Invariant: Only the thread associated with the Event/PlatformEvent |
5518 // may call park(). |
5534 // may call park(). |
5519 // TODO: assert that _Assoc != NULL or _Assoc == Self |
5535 // TODO: assert that _Assoc != NULL or _Assoc == Self |
5520 assert(_nParked == 0, "invariant"); |
5536 assert(_nParked == 0, "invariant"); |
5521 |
5537 |
5549 } |
5565 } |
5550 guarantee(_Event >= 0, "invariant"); |
5566 guarantee(_Event >= 0, "invariant"); |
5551 } |
5567 } |
5552 |
5568 |
5553 int os::PlatformEvent::park(jlong millis) { |
5569 int os::PlatformEvent::park(jlong millis) { |
|
5570 // Transitions for _Event: |
|
5571 // -1 => -1 : illegal |
|
5572 // 1 => 0 : pass - return immediately |
|
5573 // 0 => -1 : block; then set _Event to 0 before returning |
|
5574 |
5554 guarantee(_nParked == 0, "invariant"); |
5575 guarantee(_nParked == 0, "invariant"); |
5555 |
5576 |
5556 int v; |
5577 int v; |
5557 for (;;) { |
5578 for (;;) { |
5558 v = _Event; |
5579 v = _Event; |
5612 return ret; |
5633 return ret; |
5613 } |
5634 } |
5614 |
5635 |
5615 void os::PlatformEvent::unpark() { |
5636 void os::PlatformEvent::unpark() { |
5616 // Transitions for _Event: |
5637 // Transitions for _Event: |
5617 // 0 :=> 1 |
5638 // 0 => 1 : just return |
5618 // 1 :=> 1 |
5639 // 1 => 1 : just return |
5619 // -1 :=> either 0 or 1; must signal target thread |
5640 // -1 => either 0 or 1; must signal target thread |
5620 // That is, we can safely transition _Event from -1 to either |
5641 // That is, we can safely transition _Event from -1 to either |
5621 // 0 or 1. |
5642 // 0 or 1. |
5622 // See also: "Semaphores in Plan 9" by Mullender & Cox |
5643 // See also: "Semaphores in Plan 9" by Mullender & Cox |
5623 // |
5644 // |
5624 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
5645 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
5625 // that it will take two back-to-back park() calls for the owning |
5646 // that it will take two back-to-back park() calls for the owning |
5626 // thread to block. This has the benefit of forcing a spurious return |
5647 // thread to block. This has the benefit of forcing a spurious return |
5639 pthread_cond_signal(_cond); |
5660 pthread_cond_signal(_cond); |
5640 } |
5661 } |
5641 status = pthread_mutex_unlock(_mutex); |
5662 status = pthread_mutex_unlock(_mutex); |
5642 assert_status(status == 0, status, "mutex_unlock"); |
5663 assert_status(status == 0, status, "mutex_unlock"); |
5643 if (AnyWaiters != 0) { |
5664 if (AnyWaiters != 0) { |
|
5665 // Note that we signal() *after* dropping the lock for "immortal" Events. |
|
5666 // This is safe and avoids a common class of futile wakeups. In rare |
|
5667 // circumstances this can cause a thread to return prematurely from |
|
5668 // cond_{timed}wait() but the spurious wakeup is benign and the victim |
|
5669 // will simply re-test the condition and re-park itself. |
|
5670 // This provides particular benefit if the underlying platform does not |
|
5671 // provide wait morphing. |
5644 status = pthread_cond_signal(_cond); |
5672 status = pthread_cond_signal(_cond); |
5645 assert_status(status == 0, status, "cond_signal"); |
5673 assert_status(status == 0, status, "cond_signal"); |
5646 } |
5674 } |
5647 |
|
5648 // Note that we signal() _after dropping the lock for "immortal" Events. |
|
5649 // This is safe and avoids a common class of futile wakeups. In rare |
|
5650 // circumstances this can cause a thread to return prematurely from |
|
5651 // cond_{timed}wait() but the spurious wakeup is benign and the victim will |
|
5652 // simply re-test the condition and re-park itself. |
|
5653 } |
5675 } |
5654 |
5676 |
5655 |
5677 |
5656 // JSR166 |
5678 // JSR166 |
5657 // ------------------------------------------------------- |
5679 // ------------------------------------------------------- |