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