hotspot/src/os/solaris/vm/os_solaris.cpp
changeset 25472 381638db28e6
parent 25468 5331df506290
child 25477 7dad9f95fd31
equal deleted inserted replaced
25471:3ab9867d7786 25472:381638db28e6
  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) {