-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix TSAN warnings related to dfa::DFA::s0 #3311
Conversation
e016eee
to
def8cc7
Compare
Hmm, what exactly is TSAN complaining about? You added atomics in a section which is already protected by a lock (see Could this be a false positive reported by TSAN? |
The race is in |
I'm still not convinced. Both lexer and parser ATN simulators have state and edge locks to prevent concurrent access. They protect not only the DFA s0 states but also the process of adding new DFA states. Adding However I saw one case where no protection is in place:
which is not protected by the lock. Would be good to handle that properly by somehow extending the lock that was acquired in |
Here is the sanitized TSAN output.
Note that a frame or two may be missing due to optimizations. We definitely need to have that write guarded by a mutex or std::atomic. Extending |
fdf57d0
to
a9e43d8
Compare
I think I have covered all the bases. I need to revisit the whole lock setup, as those |
a9e43d8
to
f711e32
Compare
No, the locks must be static because they protect static data. The DFA is shared among all parser + lexer instances. |
@parrt Another pure C++ patch, ready for merge. |
In Java, dfa::DFA::s0 is marked as volatile and in Go it uses a mutex. The access is raw in C++ leading to TSAN warnings and undefined behavior if two threads update the pointer simultaneously. This is resolved by using std::atomic and acquire/release semantics.