equal
deleted
inserted
replaced
5438 } |
5438 } |
5439 abstime->tv_nsec = usec * 1000; |
5439 abstime->tv_nsec = usec * 1000; |
5440 return abstime; |
5440 return abstime; |
5441 } |
5441 } |
5442 |
5442 |
5443 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. |
|
5444 // Conceptually TryPark() should be equivalent to park(0). |
|
5445 |
|
5446 int os::PlatformEvent::TryPark() { |
|
5447 for (;;) { |
|
5448 const int v = _Event; |
|
5449 guarantee((v == 0) || (v == 1), "invariant"); |
|
5450 if (Atomic::cmpxchg(0, &_Event, v) == v) return v; |
|
5451 } |
|
5452 } |
|
5453 |
|
5454 void os::PlatformEvent::park() { // AKA: down() |
5443 void os::PlatformEvent::park() { // AKA: down() |
5455 // Invariant: Only the thread associated with the Event/PlatformEvent |
5444 // Invariant: Only the thread associated with the Event/PlatformEvent |
5456 // may call park(). |
5445 // may call park(). |
|
5446 assert(_nParked == 0, "invariant"); |
|
5447 |
5457 int v; |
5448 int v; |
5458 for (;;) { |
5449 for (;;) { |
5459 v = _Event; |
5450 v = _Event; |
5460 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
5451 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
5461 } |
5452 } |
5538 // Transitions for _Event: |
5529 // Transitions for _Event: |
5539 // 0 :=> 1 |
5530 // 0 :=> 1 |
5540 // 1 :=> 1 |
5531 // 1 :=> 1 |
5541 // -1 :=> either 0 or 1; must signal target thread |
5532 // -1 :=> either 0 or 1; must signal target thread |
5542 // That is, we can safely transition _Event from -1 to either |
5533 // That is, we can safely transition _Event from -1 to either |
5543 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back |
5534 // 0 or 1. |
5544 // unpark() calls. |
|
5545 // See also: "Semaphores in Plan 9" by Mullender & Cox |
5535 // See also: "Semaphores in Plan 9" by Mullender & Cox |
5546 // |
5536 // |
5547 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
5537 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
5548 // that it will take two back-to-back park() calls for the owning |
5538 // that it will take two back-to-back park() calls for the owning |
5549 // thread to block. This has the benefit of forcing a spurious return |
5539 // thread to block. This has the benefit of forcing a spurious return |
5743 jt->java_suspend_self(); |
5733 jt->java_suspend_self(); |
5744 } |
5734 } |
5745 } |
5735 } |
5746 |
5736 |
5747 void Parker::unpark() { |
5737 void Parker::unpark() { |
5748 int s, status; |
5738 int status = os::Solaris::mutex_lock(_mutex); |
5749 status = os::Solaris::mutex_lock(_mutex); |
|
5750 assert(status == 0, "invariant"); |
5739 assert(status == 0, "invariant"); |
5751 s = _counter; |
5740 const int s = _counter; |
5752 _counter = 1; |
5741 _counter = 1; |
5753 status = os::Solaris::mutex_unlock(_mutex); |
5742 status = os::Solaris::mutex_unlock(_mutex); |
5754 assert(status == 0, "invariant"); |
5743 assert(status == 0, "invariant"); |
5755 |
5744 |
5756 if (s < 1) { |
5745 if (s < 1) { |