comparison src/os/windows/vm/os_windows.cpp @ 7629:22ba8c8ce6a6

8004902: correctness fixes motivated by contended locking work (6607129) Summary: misc correctness fixes Reviewed-by: acorn, dholmes, dice, sspitsyn Contributed-by: dave.dice@oracle.com
author dcubed
date Tue, 22 Jan 2013 05:56:42 -0800
parents 203f64878aab
children 2ef7061f13b4
comparison
equal deleted inserted replaced
7628:f3184f32ce0b 7629:22ba8c8ce6a6
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 // -------------------------------------------------------