comparison src/share/vm/opto/library_call.cpp @ 17716:cdb71841f4bc

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 04d32e7fad07
children 085b304a1cc5
comparison
equal deleted inserted replaced
17713:e7cf34c87433 17716:cdb71841f4bc
3235 3235
3236 //------------------------inline_native_isInterrupted------------------ 3236 //------------------------inline_native_isInterrupted------------------
3237 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted); 3237 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
3238 bool LibraryCallKit::inline_native_isInterrupted() { 3238 bool LibraryCallKit::inline_native_isInterrupted() {
3239 // Add a fast path to t.isInterrupted(clear_int): 3239 // Add a fast path to t.isInterrupted(clear_int):
3240 // (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int)) 3240 // (t == Thread.current() &&
3241 // (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
3241 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int) 3242 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
3242 // So, in the common case that the interrupt bit is false, 3243 // So, in the common case that the interrupt bit is false,
3243 // we avoid making a call into the VM. Even if the interrupt bit 3244 // we avoid making a call into the VM. Even if the interrupt bit
3244 // is true, if the clear_int argument is false, we avoid the VM call. 3245 // is true, if the clear_int argument is false, we avoid the VM call.
3245 // However, if the receiver is not currentThread, we must call the VM, 3246 // However, if the receiver is not currentThread, we must call the VM,
3292 result_val->init_req(no_int_result_path, intcon(0)); 3293 result_val->init_req(no_int_result_path, intcon(0));
3293 3294
3294 // drop through to next case 3295 // drop through to next case
3295 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); 3296 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
3296 3297
3298 #ifndef TARGET_OS_FAMILY_windows
3297 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. 3299 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
3298 Node* clr_arg = argument(1); 3300 Node* clr_arg = argument(1);
3299 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); 3301 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0)));
3300 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne)); 3302 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne));
3301 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); 3303 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
3305 result_rgn->init_req(no_clear_result_path, false_arg); 3307 result_rgn->init_req(no_clear_result_path, false_arg);
3306 result_val->init_req(no_clear_result_path, intcon(1)); 3308 result_val->init_req(no_clear_result_path, intcon(1));
3307 3309
3308 // drop through to next case 3310 // drop through to next case
3309 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); 3311 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));
3312 #else
3313 // To return true on Windows you must read the _interrupted field
3314 // and check the the event state i.e. take the slow path.
3315 #endif // TARGET_OS_FAMILY_windows
3310 3316
3311 // (d) Otherwise, go to the slow path. 3317 // (d) Otherwise, go to the slow path.
3312 slow_region->add_req(control()); 3318 slow_region->add_req(control());
3313 set_control( _gvn.transform(slow_region)); 3319 set_control( _gvn.transform(slow_region));
3314 3320