hotspot/src/os/windows/vm/os_windows.cpp
changeset 15234 ff1f01be5fbd
parent 15228 e92acc84ade3
child 15237 9dadd171eeb8
equal deleted inserted replaced
15233:c06b129cf6c7 15234:ff1f01be5fbd
  4563            Millis -= prd ;
  4563            Millis -= prd ;
  4564        }
  4564        }
  4565     }
  4565     }
  4566     v = _Event ;
  4566     v = _Event ;
  4567     _Event = 0 ;
  4567     _Event = 0 ;
       
  4568     // see comment at end of os::PlatformEvent::park() below:
  4568     OrderAccess::fence() ;
  4569     OrderAccess::fence() ;
  4569     // If we encounter a nearly simultanous timeout expiry and unpark()
  4570     // If we encounter a nearly simultanous timeout expiry and unpark()
  4570     // we return OS_OK indicating we awoke via unpark().
  4571     // we return OS_OK indicating we awoke via unpark().
  4571     // Implementor's license -- returning OS_TIMEOUT would be equally valid, however.
  4572     // Implementor's license -- returning OS_TIMEOUT would be equally valid, however.
  4572     return (v >= 0) ? OS_OK : OS_TIMEOUT ;
  4573     return (v >= 0) ? OS_OK : OS_TIMEOUT ;
  4600     guarantee (_Event >= 0, "invariant") ;
  4601     guarantee (_Event >= 0, "invariant") ;
  4601 }
  4602 }
  4602 
  4603 
  4603 void os::PlatformEvent::unpark() {
  4604 void os::PlatformEvent::unpark() {
  4604   guarantee (_ParkHandle != NULL, "Invariant") ;
  4605   guarantee (_ParkHandle != NULL, "Invariant") ;
  4605   int v ;
  4606 
  4606   for (;;) {
  4607   // Transitions for _Event:
  4607       v = _Event ;      // Increment _Event if it's < 1.
  4608   //    0 :=> 1
  4608       if (v > 0) {
  4609   //    1 :=> 1
  4609          // If it's already signaled just return.
  4610   //   -1 :=> either 0 or 1; must signal target thread
  4610          // The LD of _Event could have reordered or be satisfied
  4611   //          That is, we can safely transition _Event from -1 to either
  4611          // by a read-aside from this processor's write buffer.
  4612   //          0 or 1. Forcing 1 is slightly more efficient for back-to-back
  4612          // To avoid problems execute a barrier and then
  4613   //          unpark() calls.
  4613          // ratify the value.  A degenerate CAS() would also work.
  4614   // See also: "Semaphores in Plan 9" by Mullender & Cox
  4614          // Viz., CAS (v+0, &_Event, v) == v).
  4615   //
  4615          OrderAccess::fence() ;
  4616   // Note: Forcing a transition from "-1" to "1" on an unpark() means
  4616          if (_Event == v) return ;
  4617   // that it will take two back-to-back park() calls for the owning
  4617          continue ;
  4618   // thread to block. This has the benefit of forcing a spurious return
  4618       }
  4619   // from the first park() call after an unpark() call which will help
  4619       if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
  4620   // shake out uses of park() and unpark() without condition variables.
  4620   }
  4621 
  4621   if (v < 0) {
  4622   if (Atomic::xchg(1, &_Event) >= 0) return;
  4622      ::SetEvent (_ParkHandle) ;
  4623 
  4623   }
  4624   ::SetEvent(_ParkHandle);
  4624 }
  4625 }
  4625 
  4626 
  4626 
  4627 
  4627 // JSR166
  4628 // JSR166
  4628 // -------------------------------------------------------
  4629 // -------------------------------------------------------