Mercurial > hg > truffle
comparison src/os/linux/vm/os_linux.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) 1999, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1999, 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. |
5006 if (status == ETIME) { status = EINTR; } | 5006 if (status == ETIME) { status = EINTR; } |
5007 assert_status(status == 0 || status == EINTR, status, "cond_wait"); | 5007 assert_status(status == 0 || status == EINTR, status, "cond_wait"); |
5008 } | 5008 } |
5009 -- _nParked ; | 5009 -- _nParked ; |
5010 | 5010 |
5011 // In theory we could move the ST of 0 into _Event past the unlock(), | |
5012 // but then we'd need a MEMBAR after the ST. | |
5013 _Event = 0 ; | 5011 _Event = 0 ; |
5014 status = pthread_mutex_unlock(_mutex); | 5012 status = pthread_mutex_unlock(_mutex); |
5015 assert_status(status == 0, status, "mutex_unlock"); | 5013 assert_status(status == 0, status, "mutex_unlock"); |
5014 // Paranoia to ensure our locked and lock-free paths interact | |
5015 // correctly with each other. | |
5016 OrderAccess::fence(); | |
5016 } | 5017 } |
5017 guarantee (_Event >= 0, "invariant") ; | 5018 guarantee (_Event >= 0, "invariant") ; |
5018 } | 5019 } |
5019 | 5020 |
5020 int os::PlatformEvent::park(jlong millis) { | 5021 int os::PlatformEvent::park(jlong millis) { |
5073 } | 5074 } |
5074 _Event = 0 ; | 5075 _Event = 0 ; |
5075 status = pthread_mutex_unlock(_mutex); | 5076 status = pthread_mutex_unlock(_mutex); |
5076 assert_status(status == 0, status, "mutex_unlock"); | 5077 assert_status(status == 0, status, "mutex_unlock"); |
5077 assert (_nParked == 0, "invariant") ; | 5078 assert (_nParked == 0, "invariant") ; |
5079 // Paranoia to ensure our locked and lock-free paths interact | |
5080 // correctly with each other. | |
5081 OrderAccess::fence(); | |
5078 return ret; | 5082 return ret; |
5079 } | 5083 } |
5080 | 5084 |
5081 void os::PlatformEvent::unpark() { | 5085 void os::PlatformEvent::unpark() { |
5082 int v, AnyWaiters ; | 5086 // Transitions for _Event: |
5083 for (;;) { | 5087 // 0 :=> 1 |
5084 v = _Event ; | 5088 // 1 :=> 1 |
5085 if (v > 0) { | 5089 // -1 :=> either 0 or 1; must signal target thread |
5086 // The LD of _Event could have reordered or be satisfied | 5090 // That is, we can safely transition _Event from -1 to either |
5087 // by a read-aside from this processor's write buffer. | 5091 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back |
5088 // To avoid problems execute a barrier and then | 5092 // unpark() calls. |
5089 // ratify the value. | 5093 // See also: "Semaphores in Plan 9" by Mullender & Cox |
5090 OrderAccess::fence() ; | 5094 // |
5091 if (_Event == v) return ; | 5095 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
5092 continue ; | 5096 // that it will take two back-to-back park() calls for the owning |
5093 } | 5097 // thread to block. This has the benefit of forcing a spurious return |
5094 if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; | 5098 // from the first park() call after an unpark() call which will help |
5095 } | 5099 // shake out uses of park() and unpark() without condition variables. |
5096 if (v < 0) { | 5100 |
5097 // Wait for the thread associated with the event to vacate | 5101 if (Atomic::xchg(1, &_Event) >= 0) return; |
5098 int status = pthread_mutex_lock(_mutex); | 5102 |
5099 assert_status(status == 0, status, "mutex_lock"); | 5103 // Wait for the thread associated with the event to vacate |
5100 AnyWaiters = _nParked ; | 5104 int status = pthread_mutex_lock(_mutex); |
5101 assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ; | 5105 assert_status(status == 0, status, "mutex_lock"); |
5102 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { | 5106 int AnyWaiters = _nParked; |
5103 AnyWaiters = 0 ; | 5107 assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant"); |
5104 pthread_cond_signal (_cond); | 5108 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { |
5105 } | 5109 AnyWaiters = 0; |
5106 status = pthread_mutex_unlock(_mutex); | 5110 pthread_cond_signal(_cond); |
5107 assert_status(status == 0, status, "mutex_unlock"); | 5111 } |
5108 if (AnyWaiters != 0) { | 5112 status = pthread_mutex_unlock(_mutex); |
5109 status = pthread_cond_signal(_cond); | 5113 assert_status(status == 0, status, "mutex_unlock"); |
5110 assert_status(status == 0, status, "cond_signal"); | 5114 if (AnyWaiters != 0) { |
5111 } | 5115 status = pthread_cond_signal(_cond); |
5116 assert_status(status == 0, status, "cond_signal"); | |
5112 } | 5117 } |
5113 | 5118 |
5114 // Note that we signal() _after dropping the lock for "immortal" Events. | 5119 // Note that we signal() _after dropping the lock for "immortal" Events. |
5115 // This is safe and avoids a common class of futile wakeups. In rare | 5120 // This is safe and avoids a common class of futile wakeups. In rare |
5116 // circumstances this can cause a thread to return prematurely from | 5121 // circumstances this can cause a thread to return prematurely from |
5192 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); | 5197 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); |
5193 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); | 5198 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); |
5194 } | 5199 } |
5195 | 5200 |
5196 void Parker::park(bool isAbsolute, jlong time) { | 5201 void Parker::park(bool isAbsolute, jlong time) { |
5202 // Ideally we'd do something useful while spinning, such | |
5203 // as calling unpackTime(). | |
5204 | |
5197 // Optional fast-path check: | 5205 // Optional fast-path check: |
5198 // Return immediately if a permit is available. | 5206 // Return immediately if a permit is available. |
5199 if (_counter > 0) { | 5207 // We depend on Atomic::xchg() having full barrier semantics |
5200 _counter = 0 ; | 5208 // since we are doing a lock-free update to _counter. |
5201 OrderAccess::fence(); | 5209 if (Atomic::xchg(0, &_counter) > 0) return; |
5202 return ; | |
5203 } | |
5204 | 5210 |
5205 Thread* thread = Thread::current(); | 5211 Thread* thread = Thread::current(); |
5206 assert(thread->is_Java_thread(), "Must be JavaThread"); | 5212 assert(thread->is_Java_thread(), "Must be JavaThread"); |
5207 JavaThread *jt = (JavaThread *)thread; | 5213 JavaThread *jt = (JavaThread *)thread; |
5208 | 5214 |
5239 int status ; | 5245 int status ; |
5240 if (_counter > 0) { // no wait needed | 5246 if (_counter > 0) { // no wait needed |
5241 _counter = 0; | 5247 _counter = 0; |
5242 status = pthread_mutex_unlock(_mutex); | 5248 status = pthread_mutex_unlock(_mutex); |
5243 assert (status == 0, "invariant") ; | 5249 assert (status == 0, "invariant") ; |
5250 // Paranoia to ensure our locked and lock-free paths interact | |
5251 // correctly with each other and Java-level accesses. | |
5244 OrderAccess::fence(); | 5252 OrderAccess::fence(); |
5245 return; | 5253 return; |
5246 } | 5254 } |
5247 | 5255 |
5248 #ifdef ASSERT | 5256 #ifdef ASSERT |
5275 #endif | 5283 #endif |
5276 | 5284 |
5277 _counter = 0 ; | 5285 _counter = 0 ; |
5278 status = pthread_mutex_unlock(_mutex) ; | 5286 status = pthread_mutex_unlock(_mutex) ; |
5279 assert_status(status == 0, status, "invariant") ; | 5287 assert_status(status == 0, status, "invariant") ; |
5288 // Paranoia to ensure our locked and lock-free paths interact | |
5289 // correctly with each other and Java-level accesses. | |
5290 OrderAccess::fence(); | |
5291 | |
5280 // If externally suspended while waiting, re-suspend | 5292 // If externally suspended while waiting, re-suspend |
5281 if (jt->handle_special_suspend_equivalent_condition()) { | 5293 if (jt->handle_special_suspend_equivalent_condition()) { |
5282 jt->java_suspend_self(); | 5294 jt->java_suspend_self(); |
5283 } | 5295 } |
5284 | |
5285 OrderAccess::fence(); | |
5286 } | 5296 } |
5287 | 5297 |
5288 void Parker::unpark() { | 5298 void Parker::unpark() { |
5289 int s, status ; | 5299 int s, status ; |
5290 status = pthread_mutex_lock(_mutex); | 5300 status = pthread_mutex_lock(_mutex); |