Mercurial > hg > graal-jvmci-8
comparison src/os/linux/vm/os_linux.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 | 7d42f3b08300 |
children | 3ac7d10a6572 9fae07c31641 |
comparison
equal
deleted
inserted
replaced
7628:f3184f32ce0b | 7629:22ba8c8ce6a6 |
---|---|
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. |
4999 if (status == ETIME) { status = EINTR; } | 4999 if (status == ETIME) { status = EINTR; } |
5000 assert_status(status == 0 || status == EINTR, status, "cond_wait"); | 5000 assert_status(status == 0 || status == EINTR, status, "cond_wait"); |
5001 } | 5001 } |
5002 -- _nParked ; | 5002 -- _nParked ; |
5003 | 5003 |
5004 // In theory we could move the ST of 0 into _Event past the unlock(), | |
5005 // but then we'd need a MEMBAR after the ST. | |
5006 _Event = 0 ; | 5004 _Event = 0 ; |
5007 status = pthread_mutex_unlock(_mutex); | 5005 status = pthread_mutex_unlock(_mutex); |
5008 assert_status(status == 0, status, "mutex_unlock"); | 5006 assert_status(status == 0, status, "mutex_unlock"); |
5007 // Paranoia to ensure our locked and lock-free paths interact | |
5008 // correctly with each other. | |
5009 OrderAccess::fence(); | |
5009 } | 5010 } |
5010 guarantee (_Event >= 0, "invariant") ; | 5011 guarantee (_Event >= 0, "invariant") ; |
5011 } | 5012 } |
5012 | 5013 |
5013 int os::PlatformEvent::park(jlong millis) { | 5014 int os::PlatformEvent::park(jlong millis) { |
5066 } | 5067 } |
5067 _Event = 0 ; | 5068 _Event = 0 ; |
5068 status = pthread_mutex_unlock(_mutex); | 5069 status = pthread_mutex_unlock(_mutex); |
5069 assert_status(status == 0, status, "mutex_unlock"); | 5070 assert_status(status == 0, status, "mutex_unlock"); |
5070 assert (_nParked == 0, "invariant") ; | 5071 assert (_nParked == 0, "invariant") ; |
5072 // Paranoia to ensure our locked and lock-free paths interact | |
5073 // correctly with each other. | |
5074 OrderAccess::fence(); | |
5071 return ret; | 5075 return ret; |
5072 } | 5076 } |
5073 | 5077 |
5074 void os::PlatformEvent::unpark() { | 5078 void os::PlatformEvent::unpark() { |
5075 int v, AnyWaiters ; | 5079 // Transitions for _Event: |
5076 for (;;) { | 5080 // 0 :=> 1 |
5077 v = _Event ; | 5081 // 1 :=> 1 |
5078 if (v > 0) { | 5082 // -1 :=> either 0 or 1; must signal target thread |
5079 // The LD of _Event could have reordered or be satisfied | 5083 // That is, we can safely transition _Event from -1 to either |
5080 // by a read-aside from this processor's write buffer. | 5084 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back |
5081 // To avoid problems execute a barrier and then | 5085 // unpark() calls. |
5082 // ratify the value. | 5086 // See also: "Semaphores in Plan 9" by Mullender & Cox |
5083 OrderAccess::fence() ; | 5087 // |
5084 if (_Event == v) return ; | 5088 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
5085 continue ; | 5089 // that it will take two back-to-back park() calls for the owning |
5086 } | 5090 // thread to block. This has the benefit of forcing a spurious return |
5087 if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; | 5091 // from the first park() call after an unpark() call which will help |
5088 } | 5092 // shake out uses of park() and unpark() without condition variables. |
5089 if (v < 0) { | 5093 |
5090 // Wait for the thread associated with the event to vacate | 5094 if (Atomic::xchg(1, &_Event) >= 0) return; |
5091 int status = pthread_mutex_lock(_mutex); | 5095 |
5092 assert_status(status == 0, status, "mutex_lock"); | 5096 // Wait for the thread associated with the event to vacate |
5093 AnyWaiters = _nParked ; | 5097 int status = pthread_mutex_lock(_mutex); |
5094 assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ; | 5098 assert_status(status == 0, status, "mutex_lock"); |
5095 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { | 5099 int AnyWaiters = _nParked; |
5096 AnyWaiters = 0 ; | 5100 assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant"); |
5097 pthread_cond_signal (_cond); | 5101 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { |
5098 } | 5102 AnyWaiters = 0; |
5099 status = pthread_mutex_unlock(_mutex); | 5103 pthread_cond_signal(_cond); |
5100 assert_status(status == 0, status, "mutex_unlock"); | 5104 } |
5101 if (AnyWaiters != 0) { | 5105 status = pthread_mutex_unlock(_mutex); |
5102 status = pthread_cond_signal(_cond); | 5106 assert_status(status == 0, status, "mutex_unlock"); |
5103 assert_status(status == 0, status, "cond_signal"); | 5107 if (AnyWaiters != 0) { |
5104 } | 5108 status = pthread_cond_signal(_cond); |
5109 assert_status(status == 0, status, "cond_signal"); | |
5105 } | 5110 } |
5106 | 5111 |
5107 // Note that we signal() _after dropping the lock for "immortal" Events. | 5112 // Note that we signal() _after dropping the lock for "immortal" Events. |
5108 // This is safe and avoids a common class of futile wakeups. In rare | 5113 // This is safe and avoids a common class of futile wakeups. In rare |
5109 // circumstances this can cause a thread to return prematurely from | 5114 // circumstances this can cause a thread to return prematurely from |
5185 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); | 5190 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); |
5186 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); | 5191 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); |
5187 } | 5192 } |
5188 | 5193 |
5189 void Parker::park(bool isAbsolute, jlong time) { | 5194 void Parker::park(bool isAbsolute, jlong time) { |
5195 // Ideally we'd do something useful while spinning, such | |
5196 // as calling unpackTime(). | |
5197 | |
5190 // Optional fast-path check: | 5198 // Optional fast-path check: |
5191 // Return immediately if a permit is available. | 5199 // Return immediately if a permit is available. |
5192 if (_counter > 0) { | 5200 // We depend on Atomic::xchg() having full barrier semantics |
5193 _counter = 0 ; | 5201 // since we are doing a lock-free update to _counter. |
5194 OrderAccess::fence(); | 5202 if (Atomic::xchg(0, &_counter) > 0) return; |
5195 return ; | |
5196 } | |
5197 | 5203 |
5198 Thread* thread = Thread::current(); | 5204 Thread* thread = Thread::current(); |
5199 assert(thread->is_Java_thread(), "Must be JavaThread"); | 5205 assert(thread->is_Java_thread(), "Must be JavaThread"); |
5200 JavaThread *jt = (JavaThread *)thread; | 5206 JavaThread *jt = (JavaThread *)thread; |
5201 | 5207 |
5232 int status ; | 5238 int status ; |
5233 if (_counter > 0) { // no wait needed | 5239 if (_counter > 0) { // no wait needed |
5234 _counter = 0; | 5240 _counter = 0; |
5235 status = pthread_mutex_unlock(_mutex); | 5241 status = pthread_mutex_unlock(_mutex); |
5236 assert (status == 0, "invariant") ; | 5242 assert (status == 0, "invariant") ; |
5243 // Paranoia to ensure our locked and lock-free paths interact | |
5244 // correctly with each other and Java-level accesses. | |
5237 OrderAccess::fence(); | 5245 OrderAccess::fence(); |
5238 return; | 5246 return; |
5239 } | 5247 } |
5240 | 5248 |
5241 #ifdef ASSERT | 5249 #ifdef ASSERT |
5268 #endif | 5276 #endif |
5269 | 5277 |
5270 _counter = 0 ; | 5278 _counter = 0 ; |
5271 status = pthread_mutex_unlock(_mutex) ; | 5279 status = pthread_mutex_unlock(_mutex) ; |
5272 assert_status(status == 0, status, "invariant") ; | 5280 assert_status(status == 0, status, "invariant") ; |
5281 // Paranoia to ensure our locked and lock-free paths interact | |
5282 // correctly with each other and Java-level accesses. | |
5283 OrderAccess::fence(); | |
5284 | |
5273 // If externally suspended while waiting, re-suspend | 5285 // If externally suspended while waiting, re-suspend |
5274 if (jt->handle_special_suspend_equivalent_condition()) { | 5286 if (jt->handle_special_suspend_equivalent_condition()) { |
5275 jt->java_suspend_self(); | 5287 jt->java_suspend_self(); |
5276 } | 5288 } |
5277 | |
5278 OrderAccess::fence(); | |
5279 } | 5289 } |
5280 | 5290 |
5281 void Parker::unpark() { | 5291 void Parker::unpark() { |
5282 int s, status ; | 5292 int s, status ; |
5283 status = pthread_mutex_lock(_mutex); | 5293 status = pthread_mutex_lock(_mutex); |