comparison src/os/solaris/vm/os_solaris.cpp @ 7643:3ac7d10a6572

Merge with hsx25/hotspot.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Thu, 31 Jan 2013 15:42:25 +0100
parents 989155e2d07a 22ba8c8ce6a6
children 5fc51c1ecdeb
comparison
equal deleted inserted replaced
7573:17b6a63fe7c2 7643:3ac7d10a6572
1 /* 1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
6012 } 6012 }
6013 -- _nParked ; 6013 -- _nParked ;
6014 _Event = 0 ; 6014 _Event = 0 ;
6015 status = os::Solaris::mutex_unlock(_mutex); 6015 status = os::Solaris::mutex_unlock(_mutex);
6016 assert_status(status == 0, status, "mutex_unlock"); 6016 assert_status(status == 0, status, "mutex_unlock");
6017 // Paranoia to ensure our locked and lock-free paths interact
6018 // correctly with each other.
6019 OrderAccess::fence();
6017 } 6020 }
6018 } 6021 }
6019 6022
6020 int os::PlatformEvent::park(jlong millis) { 6023 int os::PlatformEvent::park(jlong millis) {
6021 guarantee (_nParked == 0, "invariant") ; 6024 guarantee (_nParked == 0, "invariant") ;
6053 -- _nParked ; 6056 -- _nParked ;
6054 if (_Event >= 0) ret = OS_OK ; 6057 if (_Event >= 0) ret = OS_OK ;
6055 _Event = 0 ; 6058 _Event = 0 ;
6056 status = os::Solaris::mutex_unlock(_mutex); 6059 status = os::Solaris::mutex_unlock(_mutex);
6057 assert_status(status == 0, status, "mutex_unlock"); 6060 assert_status(status == 0, status, "mutex_unlock");
6061 // Paranoia to ensure our locked and lock-free paths interact
6062 // correctly with each other.
6063 OrderAccess::fence();
6058 return ret; 6064 return ret;
6059 } 6065 }
6060 6066
6061 void os::PlatformEvent::unpark() { 6067 void os::PlatformEvent::unpark() {
6062 int v, AnyWaiters; 6068 // Transitions for _Event:
6063 6069 // 0 :=> 1
6064 // Increment _Event. 6070 // 1 :=> 1
6065 // Another acceptable implementation would be to simply swap 1 6071 // -1 :=> either 0 or 1; must signal target thread
6066 // into _Event: 6072 // That is, we can safely transition _Event from -1 to either
6067 // if (Swap (&_Event, 1) < 0) { 6073 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back
6068 // mutex_lock (_mutex) ; AnyWaiters = nParked; mutex_unlock (_mutex) ; 6074 // unpark() calls.
6069 // if (AnyWaiters) cond_signal (_cond) ; 6075 // See also: "Semaphores in Plan 9" by Mullender & Cox
6070 // } 6076 //
6071 6077 // Note: Forcing a transition from "-1" to "1" on an unpark() means
6072 for (;;) { 6078 // that it will take two back-to-back park() calls for the owning
6073 v = _Event ; 6079 // thread to block. This has the benefit of forcing a spurious return
6074 if (v > 0) { 6080 // from the first park() call after an unpark() call which will help
6075 // The LD of _Event could have reordered or be satisfied 6081 // shake out uses of park() and unpark() without condition variables.
6076 // by a read-aside from this processor's write buffer. 6082
6077 // To avoid problems execute a barrier and then 6083 if (Atomic::xchg(1, &_Event) >= 0) return;
6078 // ratify the value. A degenerate CAS() would also work.
6079 // Viz., CAS (v+0, &_Event, v) == v).
6080 OrderAccess::fence() ;
6081 if (_Event == v) return ;
6082 continue ;
6083 }
6084 if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
6085 }
6086 6084
6087 // If the thread associated with the event was parked, wake it. 6085 // If the thread associated with the event was parked, wake it.
6088 if (v < 0) { 6086 // Wait for the thread assoc with the PlatformEvent to vacate.
6089 int status ; 6087 int status = os::Solaris::mutex_lock(_mutex);
6090 // Wait for the thread assoc with the PlatformEvent to vacate. 6088 assert_status(status == 0, status, "mutex_lock");
6091 status = os::Solaris::mutex_lock(_mutex); 6089 int AnyWaiters = _nParked;
6092 assert_status(status == 0, status, "mutex_lock"); 6090 status = os::Solaris::mutex_unlock(_mutex);
6093 AnyWaiters = _nParked ; 6091 assert_status(status == 0, status, "mutex_unlock");
6094 status = os::Solaris::mutex_unlock(_mutex); 6092 guarantee(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
6095 assert_status(status == 0, status, "mutex_unlock"); 6093 if (AnyWaiters != 0) {
6096 guarantee (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ; 6094 // We intentional signal *after* dropping the lock
6097 if (AnyWaiters != 0) { 6095 // to avoid a common class of futile wakeups.
6098 // We intentional signal *after* dropping the lock 6096 status = os::Solaris::cond_signal(_cond);
6099 // to avoid a common class of futile wakeups. 6097 assert_status(status == 0, status, "cond_signal");
6100 status = os::Solaris::cond_signal(_cond);
6101 assert_status(status == 0, status, "cond_signal");
6102 }
6103 } 6098 }
6104 } 6099 }
6105 6100
6106 // JSR166 6101 // JSR166
6107 // ------------------------------------------------------- 6102 // -------------------------------------------------------
6175 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); 6170 assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
6176 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); 6171 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
6177 } 6172 }
6178 6173
6179 void Parker::park(bool isAbsolute, jlong time) { 6174 void Parker::park(bool isAbsolute, jlong time) {
6175 // Ideally we'd do something useful while spinning, such
6176 // as calling unpackTime().
6180 6177
6181 // Optional fast-path check: 6178 // Optional fast-path check:
6182 // Return immediately if a permit is available. 6179 // Return immediately if a permit is available.
6183 if (_counter > 0) { 6180 // We depend on Atomic::xchg() having full barrier semantics
6184 _counter = 0 ; 6181 // since we are doing a lock-free update to _counter.
6185 OrderAccess::fence(); 6182 if (Atomic::xchg(0, &_counter) > 0) return;
6186 return ;
6187 }
6188 6183
6189 // Optional fast-exit: Check interrupt before trying to wait 6184 // Optional fast-exit: Check interrupt before trying to wait
6190 Thread* thread = Thread::current(); 6185 Thread* thread = Thread::current();
6191 assert(thread->is_Java_thread(), "Must be JavaThread"); 6186 assert(thread->is_Java_thread(), "Must be JavaThread");
6192 JavaThread *jt = (JavaThread *)thread; 6187 JavaThread *jt = (JavaThread *)thread;
6224 6219
6225 if (_counter > 0) { // no wait needed 6220 if (_counter > 0) { // no wait needed
6226 _counter = 0; 6221 _counter = 0;
6227 status = os::Solaris::mutex_unlock(_mutex); 6222 status = os::Solaris::mutex_unlock(_mutex);
6228 assert (status == 0, "invariant") ; 6223 assert (status == 0, "invariant") ;
6224 // Paranoia to ensure our locked and lock-free paths interact
6225 // correctly with each other and Java-level accesses.
6229 OrderAccess::fence(); 6226 OrderAccess::fence();
6230 return; 6227 return;
6231 } 6228 }
6232 6229
6233 #ifdef ASSERT 6230 #ifdef ASSERT
6265 thr_sigsetmask(SIG_SETMASK, &oldsigs, NULL); 6262 thr_sigsetmask(SIG_SETMASK, &oldsigs, NULL);
6266 #endif 6263 #endif
6267 _counter = 0 ; 6264 _counter = 0 ;
6268 status = os::Solaris::mutex_unlock(_mutex); 6265 status = os::Solaris::mutex_unlock(_mutex);
6269 assert_status(status == 0, status, "mutex_unlock") ; 6266 assert_status(status == 0, status, "mutex_unlock") ;
6267 // Paranoia to ensure our locked and lock-free paths interact
6268 // correctly with each other and Java-level accesses.
6269 OrderAccess::fence();
6270 6270
6271 // If externally suspended while waiting, re-suspend 6271 // If externally suspended while waiting, re-suspend
6272 if (jt->handle_special_suspend_equivalent_condition()) { 6272 if (jt->handle_special_suspend_equivalent_condition()) {
6273 jt->java_suspend_self(); 6273 jt->java_suspend_self();
6274 } 6274 }
6275 OrderAccess::fence();
6276 } 6275 }
6277 6276
6278 void Parker::unpark() { 6277 void Parker::unpark() {
6279 int s, status ; 6278 int s, status ;
6280 status = os::Solaris::mutex_lock (_mutex) ; 6279 status = os::Solaris::mutex_lock (_mutex) ;