comparison src/os/bsd/vm/os_bsd.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 c07c102cbad7
children 3ac7d10a6572 758935f7c23f
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.
4092 if (status == ETIMEDOUT) { status = EINTR; } 4092 if (status == ETIMEDOUT) { status = EINTR; }
4093 assert_status(status == 0 || status == EINTR, status, "cond_wait"); 4093 assert_status(status == 0 || status == EINTR, status, "cond_wait");
4094 } 4094 }
4095 -- _nParked ; 4095 -- _nParked ;
4096 4096
4097 // In theory we could move the ST of 0 into _Event past the unlock(),
4098 // but then we'd need a MEMBAR after the ST.
4099 _Event = 0 ; 4097 _Event = 0 ;
4100 status = pthread_mutex_unlock(_mutex); 4098 status = pthread_mutex_unlock(_mutex);
4101 assert_status(status == 0, status, "mutex_unlock"); 4099 assert_status(status == 0, status, "mutex_unlock");
4100 // Paranoia to ensure our locked and lock-free paths interact
4101 // correctly with each other.
4102 OrderAccess::fence();
4102 } 4103 }
4103 guarantee (_Event >= 0, "invariant") ; 4104 guarantee (_Event >= 0, "invariant") ;
4104 } 4105 }
4105 4106
4106 int os::PlatformEvent::park(jlong millis) { 4107 int os::PlatformEvent::park(jlong millis) {
4159 } 4160 }
4160 _Event = 0 ; 4161 _Event = 0 ;
4161 status = pthread_mutex_unlock(_mutex); 4162 status = pthread_mutex_unlock(_mutex);
4162 assert_status(status == 0, status, "mutex_unlock"); 4163 assert_status(status == 0, status, "mutex_unlock");
4163 assert (_nParked == 0, "invariant") ; 4164 assert (_nParked == 0, "invariant") ;
4165 // Paranoia to ensure our locked and lock-free paths interact
4166 // correctly with each other.
4167 OrderAccess::fence();
4164 return ret; 4168 return ret;
4165 } 4169 }
4166 4170
4167 void os::PlatformEvent::unpark() { 4171 void os::PlatformEvent::unpark() {
4168 int v, AnyWaiters ; 4172 // Transitions for _Event:
4169 for (;;) { 4173 // 0 :=> 1
4170 v = _Event ; 4174 // 1 :=> 1
4171 if (v > 0) { 4175 // -1 :=> either 0 or 1; must signal target thread
4172 // The LD of _Event could have reordered or be satisfied 4176 // That is, we can safely transition _Event from -1 to either
4173 // by a read-aside from this processor's write buffer. 4177 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back
4174 // To avoid problems execute a barrier and then 4178 // unpark() calls.
4175 // ratify the value. 4179 // See also: "Semaphores in Plan 9" by Mullender & Cox
4176 OrderAccess::fence() ; 4180 //
4177 if (_Event == v) return ; 4181 // Note: Forcing a transition from "-1" to "1" on an unpark() means
4178 continue ; 4182 // that it will take two back-to-back park() calls for the owning
4179 } 4183 // thread to block. This has the benefit of forcing a spurious return
4180 if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; 4184 // from the first park() call after an unpark() call which will help
4181 } 4185 // shake out uses of park() and unpark() without condition variables.
4182 if (v < 0) { 4186
4183 // Wait for the thread associated with the event to vacate 4187 if (Atomic::xchg(1, &_Event) >= 0) return;
4184 int status = pthread_mutex_lock(_mutex); 4188
4185 assert_status(status == 0, status, "mutex_lock"); 4189 // Wait for the thread associated with the event to vacate
4186 AnyWaiters = _nParked ; 4190 int status = pthread_mutex_lock(_mutex);
4187 assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ; 4191 assert_status(status == 0, status, "mutex_lock");
4188 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { 4192 int AnyWaiters = _nParked;
4189 AnyWaiters = 0 ; 4193 assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
4190 pthread_cond_signal (_cond); 4194 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
4191 } 4195 AnyWaiters = 0;
4192 status = pthread_mutex_unlock(_mutex); 4196 pthread_cond_signal(_cond);
4193 assert_status(status == 0, status, "mutex_unlock"); 4197 }
4194 if (AnyWaiters != 0) { 4198 status = pthread_mutex_unlock(_mutex);
4195 status = pthread_cond_signal(_cond); 4199 assert_status(status == 0, status, "mutex_unlock");
4196 assert_status(status == 0, status, "cond_signal"); 4200 if (AnyWaiters != 0) {
4197 } 4201 status = pthread_cond_signal(_cond);
4202 assert_status(status == 0, status, "cond_signal");
4198 } 4203 }
4199 4204
4200 // Note that we signal() _after dropping the lock for "immortal" Events. 4205 // Note that we signal() _after dropping the lock for "immortal" Events.
4201 // This is safe and avoids a common class of futile wakeups. In rare 4206 // This is safe and avoids a common class of futile wakeups. In rare
4202 // circumstances this can cause a thread to return prematurely from 4207 // circumstances this can cause a thread to return prematurely from
4278 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); 4283 assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
4279 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); 4284 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
4280 } 4285 }
4281 4286
4282 void Parker::park(bool isAbsolute, jlong time) { 4287 void Parker::park(bool isAbsolute, jlong time) {
4288 // Ideally we'd do something useful while spinning, such
4289 // as calling unpackTime().
4290
4283 // Optional fast-path check: 4291 // Optional fast-path check:
4284 // Return immediately if a permit is available. 4292 // Return immediately if a permit is available.
4285 if (_counter > 0) { 4293 // We depend on Atomic::xchg() having full barrier semantics
4286 _counter = 0 ; 4294 // since we are doing a lock-free update to _counter.
4287 OrderAccess::fence(); 4295 if (Atomic::xchg(0, &_counter) > 0) return;
4288 return ;
4289 }
4290 4296
4291 Thread* thread = Thread::current(); 4297 Thread* thread = Thread::current();
4292 assert(thread->is_Java_thread(), "Must be JavaThread"); 4298 assert(thread->is_Java_thread(), "Must be JavaThread");
4293 JavaThread *jt = (JavaThread *)thread; 4299 JavaThread *jt = (JavaThread *)thread;
4294 4300
4325 int status ; 4331 int status ;
4326 if (_counter > 0) { // no wait needed 4332 if (_counter > 0) { // no wait needed
4327 _counter = 0; 4333 _counter = 0;
4328 status = pthread_mutex_unlock(_mutex); 4334 status = pthread_mutex_unlock(_mutex);
4329 assert (status == 0, "invariant") ; 4335 assert (status == 0, "invariant") ;
4336 // Paranoia to ensure our locked and lock-free paths interact
4337 // correctly with each other and Java-level accesses.
4330 OrderAccess::fence(); 4338 OrderAccess::fence();
4331 return; 4339 return;
4332 } 4340 }
4333 4341
4334 #ifdef ASSERT 4342 #ifdef ASSERT
4361 #endif 4369 #endif
4362 4370
4363 _counter = 0 ; 4371 _counter = 0 ;
4364 status = pthread_mutex_unlock(_mutex) ; 4372 status = pthread_mutex_unlock(_mutex) ;
4365 assert_status(status == 0, status, "invariant") ; 4373 assert_status(status == 0, status, "invariant") ;
4374 // Paranoia to ensure our locked and lock-free paths interact
4375 // correctly with each other and Java-level accesses.
4376 OrderAccess::fence();
4377
4366 // If externally suspended while waiting, re-suspend 4378 // If externally suspended while waiting, re-suspend
4367 if (jt->handle_special_suspend_equivalent_condition()) { 4379 if (jt->handle_special_suspend_equivalent_condition()) {
4368 jt->java_suspend_self(); 4380 jt->java_suspend_self();
4369 } 4381 }
4370
4371 OrderAccess::fence();
4372 } 4382 }
4373 4383
4374 void Parker::unpark() { 4384 void Parker::unpark() {
4375 int s, status ; 4385 int s, status ;
4376 status = pthread_mutex_lock(_mutex); 4386 status = pthread_mutex_lock(_mutex);