comparison src/os/solaris/vm/os_solaris.cpp @ 14475:6c9332549827

6546236: Thread interrupt() of Thread.sleep() can be lost on Solaris due to race with signal handler Reviewed-by: dholmes, dcubed
author fparain
date Wed, 19 Feb 2014 16:22:15 +0000
parents 2c2a99f6cf83
children bb9356ec5967
comparison
equal deleted inserted replaced
14474:de7f1b016d55 14475:6c9332549827
330 osthread->set_saved_interrupt_thread_state(thread_state); 330 osthread->set_saved_interrupt_thread_state(thread_state);
331 thread->frame_anchor()->make_walkable(thread); 331 thread->frame_anchor()->make_walkable(thread);
332 ThreadStateTransition::transition(thread, thread_state, _thread_blocked); 332 ThreadStateTransition::transition(thread, thread_state, _thread_blocked);
333 } 333 }
334 334
335 // Version of setup_interruptible() for threads that are already in
336 // _thread_blocked. Used by os_sleep().
337 void os::Solaris::setup_interruptible_already_blocked(JavaThread* thread) {
338 thread->frame_anchor()->make_walkable(thread);
339 }
340
341 JavaThread* os::Solaris::setup_interruptible() { 335 JavaThread* os::Solaris::setup_interruptible() {
342 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); 336 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();
343 setup_interruptible(thread); 337 setup_interruptible(thread);
344 return thread; 338 return thread;
345 } 339 }
3421 3415
3422 bool os::can_execute_large_page_memory() { 3416 bool os::can_execute_large_page_memory() {
3423 return true; 3417 return true;
3424 } 3418 }
3425 3419
3426 static int os_sleep(jlong millis, bool interruptible) {
3427 const jlong limit = INT_MAX;
3428 jlong prevtime;
3429 int res;
3430
3431 while (millis > limit) {
3432 if ((res = os_sleep(limit, interruptible)) != OS_OK)
3433 return res;
3434 millis -= limit;
3435 }
3436
3437 // Restart interrupted polls with new parameters until the proper delay
3438 // has been completed.
3439
3440 prevtime = getTimeMillis();
3441
3442 while (millis > 0) {
3443 jlong newtime;
3444
3445 if (!interruptible) {
3446 // Following assert fails for os::yield_all:
3447 // assert(!thread->is_Java_thread(), "must not be java thread");
3448 res = poll(NULL, 0, millis);
3449 } else {
3450 JavaThread *jt = JavaThread::current();
3451
3452 INTERRUPTIBLE_NORESTART_VM_ALWAYS(poll(NULL, 0, millis), res, jt,
3453 os::Solaris::clear_interrupted);
3454 }
3455
3456 // INTERRUPTIBLE_NORESTART_VM_ALWAYS returns res == OS_INTRPT for
3457 // thread.Interrupt.
3458
3459 // See c/r 6751923. Poll can return 0 before time
3460 // has elapsed if time is set via clock_settime (as NTP does).
3461 // res == 0 if poll timed out (see man poll RETURN VALUES)
3462 // using the logic below checks that we really did
3463 // sleep at least "millis" if not we'll sleep again.
3464 if( ( res == 0 ) || ((res == OS_ERR) && (errno == EINTR))) {
3465 newtime = getTimeMillis();
3466 assert(newtime >= prevtime, "time moving backwards");
3467 /* Doing prevtime and newtime in microseconds doesn't help precision,
3468 and trying to round up to avoid lost milliseconds can result in a
3469 too-short delay. */
3470 millis -= newtime - prevtime;
3471 if(millis <= 0)
3472 return OS_OK;
3473 prevtime = newtime;
3474 } else
3475 return res;
3476 }
3477
3478 return OS_OK;
3479 }
3480
3481 // Read calls from inside the vm need to perform state transitions 3420 // Read calls from inside the vm need to perform state transitions
3482 size_t os::read(int fd, void *buf, unsigned int nBytes) { 3421 size_t os::read(int fd, void *buf, unsigned int nBytes) {
3483 INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); 3422 INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted);
3484 } 3423 }
3485 3424
3486 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) { 3425 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) {
3487 INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted); 3426 INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted);
3488 }
3489
3490 int os::sleep(Thread* thread, jlong millis, bool interruptible) {
3491 assert(thread == Thread::current(), "thread consistency check");
3492
3493 // TODO-FIXME: this should be removed.
3494 // On Solaris machines (especially 2.5.1) we found that sometimes the VM gets into a live lock
3495 // situation with a JavaThread being starved out of a lwp. The kernel doesn't seem to generate
3496 // a SIGWAITING signal which would enable the threads library to create a new lwp for the starving
3497 // thread. We suspect that because the Watcher thread keeps waking up at periodic intervals the kernel
3498 // is fooled into believing that the system is making progress. In the code below we block the
3499 // the watcher thread while safepoint is in progress so that it would not appear as though the
3500 // system is making progress.
3501 if (!Solaris::T2_libthread() &&
3502 thread->is_Watcher_thread() && SafepointSynchronize::is_synchronizing() && !Arguments::has_profile()) {
3503 // We now try to acquire the threads lock. Since this lock is held by the VM thread during
3504 // the entire safepoint, the watcher thread will line up here during the safepoint.
3505 Threads_lock->lock_without_safepoint_check();
3506 Threads_lock->unlock();
3507 }
3508
3509 if (thread->is_Java_thread()) {
3510 // This is a JavaThread so we honor the _thread_blocked protocol
3511 // even for sleeps of 0 milliseconds. This was originally done
3512 // as a workaround for bug 4338139. However, now we also do it
3513 // to honor the suspend-equivalent protocol.
3514
3515 JavaThread *jt = (JavaThread *) thread;
3516 ThreadBlockInVM tbivm(jt);
3517
3518 jt->set_suspend_equivalent();
3519 // cleared by handle_special_suspend_equivalent_condition() or
3520 // java_suspend_self() via check_and_wait_while_suspended()
3521
3522 int ret_code;
3523 if (millis <= 0) {
3524 thr_yield();
3525 ret_code = 0;
3526 } else {
3527 // The original sleep() implementation did not create an
3528 // OSThreadWaitState helper for sleeps of 0 milliseconds.
3529 // I'm preserving that decision for now.
3530 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
3531
3532 ret_code = os_sleep(millis, interruptible);
3533 }
3534
3535 // were we externally suspended while we were waiting?
3536 jt->check_and_wait_while_suspended();
3537
3538 return ret_code;
3539 }
3540
3541 // non-JavaThread from this point on:
3542
3543 if (millis <= 0) {
3544 thr_yield();
3545 return 0;
3546 }
3547
3548 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
3549
3550 return os_sleep(millis, interruptible);
3551 } 3427 }
3552 3428
3553 void os::naked_short_sleep(jlong ms) { 3429 void os::naked_short_sleep(jlong ms) {
3554 assert(ms < 1000, "Un-interruptable sleep, short time use only"); 3430 assert(ms < 1000, "Un-interruptable sleep, short time use only");
3555 3431
4189 // ignore 4065 // ignore
4190 } 4066 }
4191 4067
4192 errno = old_errno; 4068 errno = old_errno;
4193 } 4069 }
4194
4195
4196 void os::interrupt(Thread* thread) {
4197 assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
4198
4199 OSThread* osthread = thread->osthread();
4200
4201 int isInterrupted = osthread->interrupted();
4202 if (!isInterrupted) {
4203 osthread->set_interrupted(true);
4204 OrderAccess::fence();
4205 // os::sleep() is implemented with either poll (NULL,0,timeout) or
4206 // by parking on _SleepEvent. If the former, thr_kill will unwedge
4207 // the sleeper by SIGINTR, otherwise the unpark() will wake the sleeper.
4208 ParkEvent * const slp = thread->_SleepEvent ;
4209 if (slp != NULL) slp->unpark() ;
4210 }
4211
4212 // For JSR166: unpark after setting status but before thr_kill -dl
4213 if (thread->is_Java_thread()) {
4214 ((JavaThread*)thread)->parker()->unpark();
4215 }
4216
4217 // Handle interruptible wait() ...
4218 ParkEvent * const ev = thread->_ParkEvent ;
4219 if (ev != NULL) ev->unpark() ;
4220
4221 // When events are used everywhere for os::sleep, then this thr_kill
4222 // will only be needed if UseVMInterruptibleIO is true.
4223
4224 if (!isInterrupted) {
4225 int status = thr_kill(osthread->thread_id(), os::Solaris::SIGinterrupt());
4226 assert_status(status == 0, status, "thr_kill");
4227
4228 // Bump thread interruption counter
4229 RuntimeService::record_thread_interrupt_signaled_count();
4230 }
4231 }
4232
4233
4234 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
4235 assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
4236
4237 OSThread* osthread = thread->osthread();
4238
4239 bool res = osthread->interrupted();
4240
4241 // NOTE that since there is no "lock" around these two operations,
4242 // there is the possibility that the interrupted flag will be
4243 // "false" but that the interrupt event will be set. This is
4244 // intentional. The effect of this is that Object.wait() will appear
4245 // to have a spurious wakeup, which is not harmful, and the
4246 // possibility is so rare that it is not worth the added complexity
4247 // to add yet another lock. It has also been recommended not to put
4248 // the interrupted flag into the os::Solaris::Event structure,
4249 // because it hides the issue.
4250 if (res && clear_interrupted) {
4251 osthread->set_interrupted(false);
4252 }
4253 return res;
4254 }
4255
4256 4070
4257 void os::print_statistics() { 4071 void os::print_statistics() {
4258 } 4072 }
4259 4073
4260 int os::message_box(const char* title, const char* message) { 4074 int os::message_box(const char* title, const char* message) {