Mercurial > hg > graal-compiler
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) ; |