< prev index next >

src/hotspot/os/posix/os_posix.cpp

Print this page




1981 }
1982 
1983 void os::PlatformEvent::unpark() {
1984   // Transitions for _event:
1985   //    0 => 1 : just return
1986   //    1 => 1 : just return
1987   //   -1 => either 0 or 1; must signal target thread
1988   //         That is, we can safely transition _event from -1 to either
1989   //         0 or 1.
1990   // See also: "Semaphores in Plan 9" by Mullender & Cox
1991   //
1992   // Note: Forcing a transition from "-1" to "1" on an unpark() means
1993   // that it will take two back-to-back park() calls for the owning
1994   // thread to block. This has the benefit of forcing a spurious return
1995   // from the first park() call after an unpark() call which will help
1996   // shake out uses of park() and unpark() without checking state conditions
1997   // properly. This spurious return doesn't manifest itself in any user code
1998   // but only in the correctly written condition checking loops of ObjectMonitor,
1999   // Mutex/Monitor, Thread::muxAcquire and JavaThread::sleep
2000 
2001   if (Atomic::xchg(1, &_event) >= 0) return;
2002 
2003   int status = pthread_mutex_lock(_mutex);
2004   assert_status(status == 0, status, "mutex_lock");
2005   int anyWaiters = _nParked;
2006   assert(anyWaiters == 0 || anyWaiters == 1, "invariant");
2007   status = pthread_mutex_unlock(_mutex);
2008   assert_status(status == 0, status, "mutex_unlock");
2009 
2010   // Note that we signal() *after* dropping the lock for "immortal" Events.
2011   // This is safe and avoids a common class of futile wakeups.  In rare
2012   // circumstances this can cause a thread to return prematurely from
2013   // cond_{timed}wait() but the spurious wakeup is benign and the victim
2014   // will simply re-test the condition and re-park itself.
2015   // This provides particular benefit if the underlying platform does not
2016   // provide wait morphing.
2017 
2018   if (anyWaiters != 0) {
2019     status = pthread_cond_signal(_cond);
2020     assert_status(status == 0, status, "cond_signal");
2021   }


2029   assert_status(status == 0, status, "cond_init rel");
2030   status = pthread_cond_init(&_cond[ABS_INDEX], NULL);
2031   assert_status(status == 0, status, "cond_init abs");
2032   status = pthread_mutex_init(_mutex, _mutexAttr);
2033   assert_status(status == 0, status, "mutex_init");
2034   _cur_index = -1; // mark as unused
2035 }
2036 
2037 // Parker::park decrements count if > 0, else does a condvar wait.  Unpark
2038 // sets count to 1 and signals condvar.  Only one thread ever waits
2039 // on the condvar. Contention seen when trying to park implies that someone
2040 // is unparking you, so don't wait. And spurious returns are fine, so there
2041 // is no need to track notifications.
2042 
2043 void Parker::park(bool isAbsolute, jlong time) {
2044 
2045   // Optional fast-path check:
2046   // Return immediately if a permit is available.
2047   // We depend on Atomic::xchg() having full barrier semantics
2048   // since we are doing a lock-free update to _counter.
2049   if (Atomic::xchg(0, &_counter) > 0) return;
2050 
2051   Thread* thread = Thread::current();
2052   assert(thread->is_Java_thread(), "Must be JavaThread");
2053   JavaThread *jt = (JavaThread *)thread;
2054 
2055   // Optional optimization -- avoid state transitions if there's
2056   // an interrupt pending.
2057   if (jt->is_interrupted(false)) {
2058     return;
2059   }
2060 
2061   // Next, demultiplex/decode time arguments
2062   struct timespec absTime;
2063   if (time < 0 || (isAbsolute && time == 0)) { // don't wait at all
2064     return;
2065   }
2066   if (time > 0) {
2067     to_abstime(&absTime, time, isAbsolute, false);
2068   }
2069 




1981 }
1982 
1983 void os::PlatformEvent::unpark() {
1984   // Transitions for _event:
1985   //    0 => 1 : just return
1986   //    1 => 1 : just return
1987   //   -1 => either 0 or 1; must signal target thread
1988   //         That is, we can safely transition _event from -1 to either
1989   //         0 or 1.
1990   // See also: "Semaphores in Plan 9" by Mullender & Cox
1991   //
1992   // Note: Forcing a transition from "-1" to "1" on an unpark() means
1993   // that it will take two back-to-back park() calls for the owning
1994   // thread to block. This has the benefit of forcing a spurious return
1995   // from the first park() call after an unpark() call which will help
1996   // shake out uses of park() and unpark() without checking state conditions
1997   // properly. This spurious return doesn't manifest itself in any user code
1998   // but only in the correctly written condition checking loops of ObjectMonitor,
1999   // Mutex/Monitor, Thread::muxAcquire and JavaThread::sleep
2000 
2001   if (Atomic::xchg(&_event, 1) >= 0) return;
2002 
2003   int status = pthread_mutex_lock(_mutex);
2004   assert_status(status == 0, status, "mutex_lock");
2005   int anyWaiters = _nParked;
2006   assert(anyWaiters == 0 || anyWaiters == 1, "invariant");
2007   status = pthread_mutex_unlock(_mutex);
2008   assert_status(status == 0, status, "mutex_unlock");
2009 
2010   // Note that we signal() *after* dropping the lock for "immortal" Events.
2011   // This is safe and avoids a common class of futile wakeups.  In rare
2012   // circumstances this can cause a thread to return prematurely from
2013   // cond_{timed}wait() but the spurious wakeup is benign and the victim
2014   // will simply re-test the condition and re-park itself.
2015   // This provides particular benefit if the underlying platform does not
2016   // provide wait morphing.
2017 
2018   if (anyWaiters != 0) {
2019     status = pthread_cond_signal(_cond);
2020     assert_status(status == 0, status, "cond_signal");
2021   }


2029   assert_status(status == 0, status, "cond_init rel");
2030   status = pthread_cond_init(&_cond[ABS_INDEX], NULL);
2031   assert_status(status == 0, status, "cond_init abs");
2032   status = pthread_mutex_init(_mutex, _mutexAttr);
2033   assert_status(status == 0, status, "mutex_init");
2034   _cur_index = -1; // mark as unused
2035 }
2036 
2037 // Parker::park decrements count if > 0, else does a condvar wait.  Unpark
2038 // sets count to 1 and signals condvar.  Only one thread ever waits
2039 // on the condvar. Contention seen when trying to park implies that someone
2040 // is unparking you, so don't wait. And spurious returns are fine, so there
2041 // is no need to track notifications.
2042 
2043 void Parker::park(bool isAbsolute, jlong time) {
2044 
2045   // Optional fast-path check:
2046   // Return immediately if a permit is available.
2047   // We depend on Atomic::xchg() having full barrier semantics
2048   // since we are doing a lock-free update to _counter.
2049   if (Atomic::xchg(&_counter, 0) > 0) return;
2050 
2051   Thread* thread = Thread::current();
2052   assert(thread->is_Java_thread(), "Must be JavaThread");
2053   JavaThread *jt = (JavaThread *)thread;
2054 
2055   // Optional optimization -- avoid state transitions if there's
2056   // an interrupt pending.
2057   if (jt->is_interrupted(false)) {
2058     return;
2059   }
2060 
2061   // Next, demultiplex/decode time arguments
2062   struct timespec absTime;
2063   if (time < 0 || (isAbsolute && time == 0)) { // don't wait at all
2064     return;
2065   }
2066   if (time > 0) {
2067     to_abstime(&absTime, time, isAbsolute, false);
2068   }
2069 


< prev index next >