|
Revision tags: llvmorg-20.1.0, llvmorg-20.1.0-rc3, llvmorg-20.1.0-rc2, llvmorg-20.1.0-rc1, llvmorg-21-init, llvmorg-19.1.7, llvmorg-19.1.6, llvmorg-19.1.5, llvmorg-19.1.4, llvmorg-19.1.3, llvmorg-19.1.2, llvmorg-19.1.1, llvmorg-19.1.0, llvmorg-19.1.0-rc4, llvmorg-19.1.0-rc3, llvmorg-19.1.0-rc2, llvmorg-19.1.0-rc1, llvmorg-20-init, llvmorg-18.1.8, llvmorg-18.1.7, llvmorg-18.1.6, llvmorg-18.1.5, llvmorg-18.1.4, llvmorg-18.1.3, llvmorg-18.1.2, llvmorg-18.1.1, llvmorg-18.1.0, llvmorg-18.1.0-rc4, llvmorg-18.1.0-rc3, llvmorg-18.1.0-rc2, llvmorg-18.1.0-rc1, llvmorg-19-init, llvmorg-17.0.6, llvmorg-17.0.5, llvmorg-17.0.4, llvmorg-17.0.3, llvmorg-17.0.2, llvmorg-17.0.1, llvmorg-17.0.0, llvmorg-17.0.0-rc4, llvmorg-17.0.0-rc3, llvmorg-17.0.0-rc2, llvmorg-17.0.0-rc1, llvmorg-18-init, llvmorg-16.0.6, llvmorg-16.0.5, llvmorg-16.0.4, llvmorg-16.0.3, llvmorg-16.0.2, llvmorg-16.0.1, llvmorg-16.0.0, llvmorg-16.0.0-rc4, llvmorg-16.0.0-rc3, llvmorg-16.0.0-rc2, llvmorg-16.0.0-rc1, llvmorg-17-init, llvmorg-15.0.7, llvmorg-15.0.6, llvmorg-15.0.5, llvmorg-15.0.4, llvmorg-15.0.3, llvmorg-15.0.2, llvmorg-15.0.1, llvmorg-15.0.0, llvmorg-15.0.0-rc3, llvmorg-15.0.0-rc2, llvmorg-15.0.0-rc1, llvmorg-16-init, llvmorg-14.0.6, llvmorg-14.0.5, llvmorg-14.0.4, llvmorg-14.0.3, llvmorg-14.0.2, llvmorg-14.0.1, llvmorg-14.0.0, llvmorg-14.0.0-rc4, llvmorg-14.0.0-rc3, llvmorg-14.0.0-rc2, llvmorg-14.0.0-rc1, llvmorg-15-init, llvmorg-13.0.1, llvmorg-13.0.1-rc3, llvmorg-13.0.1-rc2, llvmorg-13.0.1-rc1, llvmorg-13.0.0, llvmorg-13.0.0-rc4, llvmorg-13.0.0-rc3, llvmorg-13.0.0-rc2, llvmorg-13.0.0-rc1, llvmorg-14-init, llvmorg-12.0.1, llvmorg-12.0.1-rc4, llvmorg-12.0.1-rc3, llvmorg-12.0.1-rc2, llvmorg-12.0.1-rc1, llvmorg-12.0.0, llvmorg-12.0.0-rc5, llvmorg-12.0.0-rc4, llvmorg-12.0.0-rc3, llvmorg-12.0.0-rc2, llvmorg-11.1.0, llvmorg-11.1.0-rc3, llvmorg-12.0.0-rc1, llvmorg-13-init, llvmorg-11.1.0-rc2, llvmorg-11.1.0-rc1, llvmorg-11.0.1, llvmorg-11.0.1-rc2, llvmorg-11.0.1-rc1, llvmorg-11.0.0, llvmorg-11.0.0-rc6, llvmorg-11.0.0-rc5, llvmorg-11.0.0-rc4, llvmorg-11.0.0-rc3, llvmorg-11.0.0-rc2, llvmorg-11.0.0-rc1, llvmorg-12-init, llvmorg-10.0.1, llvmorg-10.0.1-rc4, llvmorg-10.0.1-rc3, llvmorg-10.0.1-rc2 |
| #
4408eeed |
| 23-May-2020 |
Dmitry Vyukov <[email protected]> |
tsan: fix false positives in AcquireGlobal
Add ThreadClock:: global_acquire_ which is the last time another thread has done a global acquire of this thread's clock.
It helps to avoid problem descri
tsan: fix false positives in AcquireGlobal
Add ThreadClock:: global_acquire_ which is the last time another thread has done a global acquire of this thread's clock.
It helps to avoid problem described in: https://github.com/golang/go/issues/39186 See test/tsan/java_finalizer2.cpp for a regression test. Note the failuire is _extremely_ hard to hit, so if you are trying to reproduce it, you may want to run something like: $ go get golang.org/x/tools/cmd/stress $ stress -p=64 ./a.out
The crux of the problem is roughly as follows. A number of O(1) optimizations in the clocks algorithm assume proper transitive cumulative propagation of clock values. The AcquireGlobal operation may produce an inconsistent non-linearazable view of thread clocks. Namely, it may acquire a later value from a thread with a higher ID, but fail to acquire an earlier value from a thread with a lower ID. If a thread that executed AcquireGlobal then releases to a sync clock, it will spoil the sync clock with the inconsistent values. If another thread later releases to the sync clock, the optimized algorithm may break.
The exact sequence of events that leads to the failure. - thread 1 executes AcquireGlobal - thread 1 acquires value 1 for thread 2 - thread 2 increments clock to 2 - thread 2 releases to sync object 1 - thread 3 at time 1 - thread 3 acquires from sync object 1 - thread 1 acquires value 1 for thread 3 - thread 1 releases to sync object 2 - sync object 2 clock has 1 for thread 2 and 1 for thread 3 - thread 3 releases to sync object 2 - thread 3 sees value 1 in the clock for itself and decides that it has already released to the clock and did not acquire anything from other threads after that (the last_acquire_ check in release operation) - thread 3 does not update the value for thread 2 in the clock from 1 to 2 - thread 4 acquires from sync object 2 - thread 4 detects a false race with thread 2 as it should have been synchronized with thread 2 up to time 2, but because of the broken clock it is now synchronized only up to time 1
The global_acquire_ value helps to prevent this scenario. Namely, thread 3 will not trust any own clock values up to global_acquire_ for the purposes of the last_acquire_ optimization.
Reviewed-in: https://reviews.llvm.org/D80474 Reported-by: nvanbenschoten (Nathan VanBenschoten)
show more ...
|