comparison src/share/vm/opto/library_call.cpp @ 14649:f6301b007a16

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 0f19095fd8c1
children ef7328717719
comparison
equal deleted inserted replaced
14648:4c76be9856fc 14649:f6301b007a16
3244 3244
3245 //------------------------inline_native_isInterrupted------------------ 3245 //------------------------inline_native_isInterrupted------------------
3246 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted); 3246 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted);
3247 bool LibraryCallKit::inline_native_isInterrupted() { 3247 bool LibraryCallKit::inline_native_isInterrupted() {
3248 // Add a fast path to t.isInterrupted(clear_int): 3248 // Add a fast path to t.isInterrupted(clear_int):
3249 // (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int)) 3249 // (t == Thread.current() &&
3250 // (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int)))
3250 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int) 3251 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int)
3251 // So, in the common case that the interrupt bit is false, 3252 // So, in the common case that the interrupt bit is false,
3252 // we avoid making a call into the VM. Even if the interrupt bit 3253 // we avoid making a call into the VM. Even if the interrupt bit
3253 // is true, if the clear_int argument is false, we avoid the VM call. 3254 // is true, if the clear_int argument is false, we avoid the VM call.
3254 // However, if the receiver is not currentThread, we must call the VM, 3255 // However, if the receiver is not currentThread, we must call the VM,
3301 result_val->init_req(no_int_result_path, intcon(0)); 3302 result_val->init_req(no_int_result_path, intcon(0));
3302 3303
3303 // drop through to next case 3304 // drop through to next case
3304 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); 3305 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)));
3305 3306
3307 #ifndef TARGET_OS_FAMILY_windows
3306 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. 3308 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
3307 Node* clr_arg = argument(1); 3309 Node* clr_arg = argument(1);
3308 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); 3310 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0)));
3309 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne)); 3311 Node* bol_arg = _gvn.transform(new (C) BoolNode(cmp_arg, BoolTest::ne));
3310 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN); 3312 IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
3314 result_rgn->init_req(no_clear_result_path, false_arg); 3316 result_rgn->init_req(no_clear_result_path, false_arg);
3315 result_val->init_req(no_clear_result_path, intcon(1)); 3317 result_val->init_req(no_clear_result_path, intcon(1));
3316 3318
3317 // drop through to next case 3319 // drop through to next case
3318 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); 3320 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)));
3321 #else
3322 // To return true on Windows you must read the _interrupted field
3323 // and check the the event state i.e. take the slow path.
3324 #endif // TARGET_OS_FAMILY_windows
3319 3325
3320 // (d) Otherwise, go to the slow path. 3326 // (d) Otherwise, go to the slow path.
3321 slow_region->add_req(control()); 3327 slow_region->add_req(control());
3322 set_control( _gvn.transform(slow_region)); 3328 set_control( _gvn.transform(slow_region));
3323 3329