comparison src/os/posix/vm/os_posix.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 c250880a6673
children bb9356ec5967
comparison
equal deleted inserted replaced
14474:de7f1b016d55 14475:6c9332549827
1 /* 1 /*
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1999, 2014, 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.
22 * 22 *
23 */ 23 */
24 24
25 #include "prims/jvm.h" 25 #include "prims/jvm.h"
26 #include "runtime/frame.inline.hpp" 26 #include "runtime/frame.inline.hpp"
27 #include "runtime/interfaceSupport.hpp"
27 #include "runtime/os.hpp" 28 #include "runtime/os.hpp"
28 #include "utilities/vmError.hpp" 29 #include "utilities/vmError.hpp"
29 30
30 #include <unistd.h> 31 #include <unistd.h>
31 #include <sys/resource.h> 32 #include <sys/resource.h>
305 strncat(agent_entry_name, lib_name, name_len); 306 strncat(agent_entry_name, lib_name, name_len);
306 } 307 }
307 return agent_entry_name; 308 return agent_entry_name;
308 } 309 }
309 310
311 int os::sleep(Thread* thread, jlong millis, bool interruptible) {
312 assert(thread == Thread::current(), "thread consistency check");
313
314 ParkEvent * const slp = thread->_SleepEvent ;
315 slp->reset() ;
316 OrderAccess::fence() ;
317
318 if (interruptible) {
319 jlong prevtime = javaTimeNanos();
320
321 for (;;) {
322 if (os::is_interrupted(thread, true)) {
323 return OS_INTRPT;
324 }
325
326 jlong newtime = javaTimeNanos();
327
328 if (newtime - prevtime < 0) {
329 // time moving backwards, should only happen if no monotonic clock
330 // not a guarantee() because JVM should not abort on kernel/glibc bugs
331 assert(!os::supports_monotonic_clock(), "unexpected time moving backwards detected in os::sleep(interruptible)");
332 } else {
333 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
334 }
335
336 if (millis <= 0) {
337 return OS_OK;
338 }
339
340 prevtime = newtime;
341
342 {
343 assert(thread->is_Java_thread(), "sanity check");
344 JavaThread *jt = (JavaThread *) thread;
345 ThreadBlockInVM tbivm(jt);
346 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
347
348 jt->set_suspend_equivalent();
349 // cleared by handle_special_suspend_equivalent_condition() or
350 // java_suspend_self() via check_and_wait_while_suspended()
351
352 slp->park(millis);
353
354 // were we externally suspended while we were waiting?
355 jt->check_and_wait_while_suspended();
356 }
357 }
358 } else {
359 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
360 jlong prevtime = javaTimeNanos();
361
362 for (;;) {
363 // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
364 // the 1st iteration ...
365 jlong newtime = javaTimeNanos();
366
367 if (newtime - prevtime < 0) {
368 // time moving backwards, should only happen if no monotonic clock
369 // not a guarantee() because JVM should not abort on kernel/glibc bugs
370 assert(!os::supports_monotonic_clock(), "unexpected time moving backwards detected on os::sleep(!interruptible)");
371 } else {
372 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
373 }
374
375 if (millis <= 0) break ;
376
377 prevtime = newtime;
378 slp->park(millis);
379 }
380 return OS_OK ;
381 }
382 }
383
384 ////////////////////////////////////////////////////////////////////////////////
385 // interrupt support
386
387 void os::interrupt(Thread* thread) {
388 assert(Thread::current() == thread || Threads_lock->owned_by_self(),
389 "possibility of dangling Thread pointer");
390
391 OSThread* osthread = thread->osthread();
392
393 if (!osthread->interrupted()) {
394 osthread->set_interrupted(true);
395 // More than one thread can get here with the same value of osthread,
396 // resulting in multiple notifications. We do, however, want the store
397 // to interrupted() to be visible to other threads before we execute unpark().
398 OrderAccess::fence();
399 ParkEvent * const slp = thread->_SleepEvent ;
400 if (slp != NULL) slp->unpark() ;
401 }
402
403 // For JSR166. Unpark even if interrupt status already was set
404 if (thread->is_Java_thread())
405 ((JavaThread*)thread)->parker()->unpark();
406
407 ParkEvent * ev = thread->_ParkEvent ;
408 if (ev != NULL) ev->unpark() ;
409
410 }
411
412 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
413 assert(Thread::current() == thread || Threads_lock->owned_by_self(),
414 "possibility of dangling Thread pointer");
415
416 OSThread* osthread = thread->osthread();
417
418 bool interrupted = osthread->interrupted();
419
420 // NOTE that since there is no "lock" around the interrupt and
421 // is_interrupted operations, there is the possibility that the
422 // interrupted flag (in osThread) will be "false" but that the
423 // low-level events will be in the signaled state. This is
424 // intentional. The effect of this is that Object.wait() and
425 // LockSupport.park() will appear to have a spurious wakeup, which
426 // is allowed and not harmful, and the possibility is so rare that
427 // it is not worth the added complexity to add yet another lock.
428 // For the sleep event an explicit reset is performed on entry
429 // to os::sleep, so there is no early return. It has also been
430 // recommended not to put the interrupted flag into the "event"
431 // structure because it hides the issue.
432 if (interrupted && clear_interrupted) {
433 osthread->set_interrupted(false);
434 // consider thread->_SleepEvent->reset() ... optional optimization
435 }
436
437 return interrupted;
438 }
439
310 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { 440 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() {
311 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); 441 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread");
312 } 442 }
313 443
314 /* 444 /*