equal
deleted
inserted
replaced
5455 abstime->tv_nsec = usec * 1000; |
5455 abstime->tv_nsec = usec * 1000; |
5456 } |
5456 } |
5457 return abstime; |
5457 return abstime; |
5458 } |
5458 } |
5459 |
5459 |
5460 |
|
5461 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. |
|
5462 // Conceptually TryPark() should be equivalent to park(0). |
|
5463 |
|
5464 int os::PlatformEvent::TryPark() { |
|
5465 for (;;) { |
|
5466 const int v = _Event; |
|
5467 guarantee((v == 0) || (v == 1), "invariant"); |
|
5468 if (Atomic::cmpxchg(0, &_Event, v) == v) return v; |
|
5469 } |
|
5470 } |
|
5471 |
|
5472 void os::PlatformEvent::park() { // AKA "down()" |
5460 void os::PlatformEvent::park() { // AKA "down()" |
5473 // Invariant: Only the thread associated with the Event/PlatformEvent |
5461 // Invariant: Only the thread associated with the Event/PlatformEvent |
5474 // may call park(). |
5462 // may call park(). |
5475 // TODO: assert that _Assoc != NULL or _Assoc == Self |
5463 // TODO: assert that _Assoc != NULL or _Assoc == Self |
|
5464 assert(_nParked == 0, "invariant"); |
|
5465 |
5476 int v; |
5466 int v; |
5477 for (;;) { |
5467 for (;;) { |
5478 v = _Event; |
5468 v = _Event; |
5479 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
5469 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
5480 } |
5470 } |
5570 // Transitions for _Event: |
5560 // Transitions for _Event: |
5571 // 0 :=> 1 |
5561 // 0 :=> 1 |
5572 // 1 :=> 1 |
5562 // 1 :=> 1 |
5573 // -1 :=> either 0 or 1; must signal target thread |
5563 // -1 :=> either 0 or 1; must signal target thread |
5574 // That is, we can safely transition _Event from -1 to either |
5564 // That is, we can safely transition _Event from -1 to either |
5575 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back |
5565 // 0 or 1. |
5576 // unpark() calls. |
|
5577 // See also: "Semaphores in Plan 9" by Mullender & Cox |
5566 // See also: "Semaphores in Plan 9" by Mullender & Cox |
5578 // |
5567 // |
5579 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
5568 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
5580 // that it will take two back-to-back park() calls for the owning |
5569 // that it will take two back-to-back park() calls for the owning |
5581 // thread to block. This has the benefit of forcing a spurious return |
5570 // thread to block. This has the benefit of forcing a spurious return |
5799 jt->java_suspend_self(); |
5788 jt->java_suspend_self(); |
5800 } |
5789 } |
5801 } |
5790 } |
5802 |
5791 |
5803 void Parker::unpark() { |
5792 void Parker::unpark() { |
5804 int s, status; |
5793 int status = pthread_mutex_lock(_mutex); |
5805 status = pthread_mutex_lock(_mutex); |
|
5806 assert(status == 0, "invariant"); |
5794 assert(status == 0, "invariant"); |
5807 s = _counter; |
5795 const int s = _counter; |
5808 _counter = 1; |
5796 _counter = 1; |
5809 if (s < 1) { |
5797 if (s < 1) { |
5810 // thread might be parked |
5798 // thread might be parked |
5811 if (_cur_index != -1) { |
5799 if (_cur_index != -1) { |
5812 // thread is definitely parked |
5800 // thread is definitely parked |