hotspot/src/os/linux/vm/os_linux.cpp
changeset 36087 c7770c4909d0
parent 35884 ec439aaca107
child 36089 0df0a643796e
equal deleted inserted replaced
36085:222ab7d1a9bf 36087:c7770c4909d0
  5347 //   -1 : thread is blocked, i.e. there is a waiter
  5347 //   -1 : thread is blocked, i.e. there is a waiter
  5348 //    0 : neutral: thread is running or ready,
  5348 //    0 : neutral: thread is running or ready,
  5349 //        could have been signaled after a wait started
  5349 //        could have been signaled after a wait started
  5350 //    1 : signaled - thread is running or ready
  5350 //    1 : signaled - thread is running or ready
  5351 //
  5351 //
  5352 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
       
  5353 // hang indefinitely.  For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
       
  5354 // For specifics regarding the bug see GLIBC BUGID 261237 :
       
  5355 //    http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
       
  5356 // Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
       
  5357 // will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
       
  5358 // is used.  (The simple C test-case provided in the GLIBC bug report manifests the
       
  5359 // hang).  The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
       
  5360 // and monitorenter when we're using 1-0 locking.  All those operations may result in
       
  5361 // calls to pthread_cond_timedwait().  Using LD_ASSUME_KERNEL to use an older version
       
  5362 // of libpthread avoids the problem, but isn't practical.
       
  5363 //
       
  5364 // Possible remedies:
       
  5365 //
       
  5366 // 1.   Establish a minimum relative wait time.  50 to 100 msecs seems to work.
       
  5367 //      This is palliative and probabilistic, however.  If the thread is preempted
       
  5368 //      between the call to compute_abstime() and pthread_cond_timedwait(), more
       
  5369 //      than the minimum period may have passed, and the abstime may be stale (in the
       
  5370 //      past) resultin in a hang.   Using this technique reduces the odds of a hang
       
  5371 //      but the JVM is still vulnerable, particularly on heavily loaded systems.
       
  5372 //
       
  5373 // 2.   Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
       
  5374 //      of the usual flag-condvar-mutex idiom.  The write side of the pipe is set
       
  5375 //      NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
       
  5376 //      reduces to poll()+read().  This works well, but consumes 2 FDs per extant
       
  5377 //      thread.
       
  5378 //
       
  5379 // 3.   Embargo pthread_cond_timedwait() and implement a native "chron" thread
       
  5380 //      that manages timeouts.  We'd emulate pthread_cond_timedwait() by enqueuing
       
  5381 //      a timeout request to the chron thread and then blocking via pthread_cond_wait().
       
  5382 //      This also works well.  In fact it avoids kernel-level scalability impediments
       
  5383 //      on certain platforms that don't handle lots of active pthread_cond_timedwait()
       
  5384 //      timers in a graceful fashion.
       
  5385 //
       
  5386 // 4.   When the abstime value is in the past it appears that control returns
       
  5387 //      correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
       
  5388 //      Subsequent timedwait/wait calls may hang indefinitely.  Given that, we
       
  5389 //      can avoid the problem by reinitializing the condvar -- by cond_destroy()
       
  5390 //      followed by cond_init() -- after all calls to pthread_cond_timedwait().
       
  5391 //      It may be possible to avoid reinitialization by checking the return
       
  5392 //      value from pthread_cond_timedwait().  In addition to reinitializing the
       
  5393 //      condvar we must establish the invariant that cond_signal() is only called
       
  5394 //      within critical sections protected by the adjunct mutex.  This prevents
       
  5395 //      cond_signal() from "seeing" a condvar that's in the midst of being
       
  5396 //      reinitialized or that is corrupt.  Sadly, this invariant obviates the
       
  5397 //      desirable signal-after-unlock optimization that avoids futile context switching.
       
  5398 //
       
  5399 //      I'm also concerned that some versions of NTPL might allocate an auxilliary
       
  5400 //      structure when a condvar is used or initialized.  cond_destroy()  would
       
  5401 //      release the helper structure.  Our reinitialize-after-timedwait fix
       
  5402 //      put excessive stress on malloc/free and locks protecting the c-heap.
       
  5403 //
       
  5404 // We currently use (4).  See the WorkAroundNTPLTimedWaitHang flag.
       
  5405 // It may be possible to refine (4) by checking the kernel and NTPL verisons
       
  5406 // and only enabling the work-around for vulnerable environments.
       
  5407 
  5352 
  5408 // utility to compute the abstime argument to timedwait:
  5353 // utility to compute the abstime argument to timedwait:
  5409 // millis is the relative timeout time
  5354 // millis is the relative timeout time
  5410 // abstime will be the absolute timeout time
  5355 // abstime will be the absolute timeout time
  5411 // TODO: replace compute_abstime() with unpackTime()
  5356 // TODO: replace compute_abstime() with unpackTime()
  5527   // TODO: properly differentiate simultaneous notify+interrupt.
  5472   // TODO: properly differentiate simultaneous notify+interrupt.
  5528   // In that case, we should propagate the notify to another waiter.
  5473   // In that case, we should propagate the notify to another waiter.
  5529 
  5474 
  5530   while (_Event < 0) {
  5475   while (_Event < 0) {
  5531     status = pthread_cond_timedwait(_cond, _mutex, &abst);
  5476     status = pthread_cond_timedwait(_cond, _mutex, &abst);
  5532     if (status != 0 && WorkAroundNPTLTimedWaitHang) {
       
  5533       pthread_cond_destroy(_cond);
       
  5534       pthread_cond_init(_cond, os::Linux::condAttr());
       
  5535     }
       
  5536     assert_status(status == 0 || status == EINTR ||
  5477     assert_status(status == 0 || status == EINTR ||
  5537                   status == ETIME || status == ETIMEDOUT,
  5478                   status == ETIME || status == ETIMEDOUT,
  5538                   status, "cond_timedwait");
  5479                   status, "cond_timedwait");
  5539     if (!FilterSpuriousWakeups) break;                 // previous semantics
  5480     if (!FilterSpuriousWakeups) break;                 // previous semantics
  5540     if (status == ETIME || status == ETIMEDOUT) break;
  5481     if (status == ETIME || status == ETIMEDOUT) break;
  5574   // Wait for the thread associated with the event to vacate
  5515   // Wait for the thread associated with the event to vacate
  5575   int status = pthread_mutex_lock(_mutex);
  5516   int status = pthread_mutex_lock(_mutex);
  5576   assert_status(status == 0, status, "mutex_lock");
  5517   assert_status(status == 0, status, "mutex_lock");
  5577   int AnyWaiters = _nParked;
  5518   int AnyWaiters = _nParked;
  5578   assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
  5519   assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
  5579   if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
       
  5580     AnyWaiters = 0;
       
  5581     pthread_cond_signal(_cond);
       
  5582   }
       
  5583   status = pthread_mutex_unlock(_mutex);
  5520   status = pthread_mutex_unlock(_mutex);
  5584   assert_status(status == 0, status, "mutex_unlock");
  5521   assert_status(status == 0, status, "mutex_unlock");
  5585   if (AnyWaiters != 0) {
  5522   if (AnyWaiters != 0) {
  5586     // Note that we signal() *after* dropping the lock for "immortal" Events.
  5523     // Note that we signal() *after* dropping the lock for "immortal" Events.
  5587     // This is safe and avoids a common class of  futile wakeups.  In rare
  5524     // This is safe and avoids a common class of  futile wakeups.  In rare
  5729 
  5666 
  5730   int status;
  5667   int status;
  5731   if (_counter > 0)  { // no wait needed
  5668   if (_counter > 0)  { // no wait needed
  5732     _counter = 0;
  5669     _counter = 0;
  5733     status = pthread_mutex_unlock(_mutex);
  5670     status = pthread_mutex_unlock(_mutex);
  5734     assert(status == 0, "invariant");
  5671     assert_status(status == 0, status, "invariant");
  5735     // Paranoia to ensure our locked and lock-free paths interact
  5672     // Paranoia to ensure our locked and lock-free paths interact
  5736     // correctly with each other and Java-level accesses.
  5673     // correctly with each other and Java-level accesses.
  5737     OrderAccess::fence();
  5674     OrderAccess::fence();
  5738     return;
  5675     return;
  5739   }
  5676   }
  5755     _cur_index = REL_INDEX; // arbitrary choice when not timed
  5692     _cur_index = REL_INDEX; // arbitrary choice when not timed
  5756     status = pthread_cond_wait(&_cond[_cur_index], _mutex);
  5693     status = pthread_cond_wait(&_cond[_cur_index], _mutex);
  5757   } else {
  5694   } else {
  5758     _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
  5695     _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
  5759     status = pthread_cond_timedwait(&_cond[_cur_index], _mutex, &absTime);
  5696     status = pthread_cond_timedwait(&_cond[_cur_index], _mutex, &absTime);
  5760     if (status != 0 && WorkAroundNPTLTimedWaitHang) {
       
  5761       pthread_cond_destroy(&_cond[_cur_index]);
       
  5762       pthread_cond_init(&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr());
       
  5763     }
       
  5764   }
  5697   }
  5765   _cur_index = -1;
  5698   _cur_index = -1;
  5766   assert_status(status == 0 || status == EINTR ||
  5699   assert_status(status == 0 || status == EINTR ||
  5767                 status == ETIME || status == ETIMEDOUT,
  5700                 status == ETIME || status == ETIMEDOUT,
  5768                 status, "cond_timedwait");
  5701                 status, "cond_timedwait");
  5784   }
  5717   }
  5785 }
  5718 }
  5786 
  5719 
  5787 void Parker::unpark() {
  5720 void Parker::unpark() {
  5788   int status = pthread_mutex_lock(_mutex);
  5721   int status = pthread_mutex_lock(_mutex);
  5789   assert(status == 0, "invariant");
  5722   assert_status(status == 0, status, "invariant");
  5790   const int s = _counter;
  5723   const int s = _counter;
  5791   _counter = 1;
  5724   _counter = 1;
  5792   if (s < 1) {
  5725   // must capture correct index before unlocking
  5793     // thread might be parked
  5726   int index = _cur_index;
  5794     if (_cur_index != -1) {
  5727   status = pthread_mutex_unlock(_mutex);
  5795       // thread is definitely parked
  5728   assert_status(status == 0, status, "invariant");
  5796       if (WorkAroundNPTLTimedWaitHang) {
  5729   if (s < 1 && _cur_index != -1) {
  5797         status = pthread_cond_signal(&_cond[_cur_index]);
  5730     // thread is definitely parked
  5798         assert(status == 0, "invariant");
  5731     status = pthread_cond_signal(&_cond[index]);
  5799         status = pthread_mutex_unlock(_mutex);
  5732     assert_status(status == 0, status, "invariant");
  5800         assert(status == 0, "invariant");
       
  5801       } else {
       
  5802         // must capture correct index before unlocking
       
  5803         int index = _cur_index;
       
  5804         status = pthread_mutex_unlock(_mutex);
       
  5805         assert(status == 0, "invariant");
       
  5806         status = pthread_cond_signal(&_cond[index]);
       
  5807         assert(status == 0, "invariant");
       
  5808       }
       
  5809     } else {
       
  5810       pthread_mutex_unlock(_mutex);
       
  5811       assert(status == 0, "invariant");
       
  5812     }
       
  5813   } else {
       
  5814     pthread_mutex_unlock(_mutex);
       
  5815     assert(status == 0, "invariant");
       
  5816   }
  5733   }
  5817 }
  5734 }
  5818 
  5735 
  5819 
  5736 
  5820 extern char** environ;
  5737 extern char** environ;