Mercurial > hg > truffle
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 |