Skip to content
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

Synchronize accesses to reachability handlers #7736

Merged
merged 1 commit into from
Nov 24, 2023

Conversation

zakkak
Copy link
Collaborator

@zakkak zakkak commented Nov 6, 2023

Prevents data races in reachability handlers registration when using
-H:-RunReachabilityHandlersConcurrently.

The fact that #5868 is not deterministic and it's related to enabling/disabling concurrency hints that it's probably caused by a data race.
Adding a synchonized blocks in com.oracle.svm.hosted.ReachabilityHandlerFeature#registerReachabilityHandler(org.graalvm.nativeimage.hosted.Feature.BeforeAnalysisAccess, java.lang.Object, java.lang.Object[]) seems to resolve the issue.

Closes #5868

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Nov 6, 2023
Copy link

@christianwimmer christianwimmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of the explicit synchronized blocks, it would be better to use proper synchronized data structures. For ReachabilityHandlerFeature.activeHandlers and triggeredHandlers that would be wrapping using Collections.synchronizedMap, while for the nested set that does not require identity semantics we can just use ConcurrentHashMap.createKeySet.

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 7, 2023

Hi @christianwimmer I see there is com.oracle.svm.core.util.ConcurrentIdentityHashMap as well, shall I use it instead of Collections.synchronizedMap for better performance?

@zakkak zakkak force-pushed the 2023-11-06-fix-5868 branch 2 times, most recently from e6190e3 to c4f2371 Compare November 7, 2023 12:49
@christianwimmer
Copy link

Hi @christianwimmer I see there is com.oracle.svm.core.util.ConcurrentIdentityHashMap as well, shall I use it instead of Collections.synchronizedMap for better performance?

Yes, I forgot that we have that.

@@ -119,7 +122,7 @@ public void duringAnalysis(DuringAnalysisAccess a) {
Set<Object> triggers = activeHandlers.get(callback);
if (callback instanceof Consumer) {
if (isTriggered(access, triggers)) {
triggeredHandlers.put(callback, null);
triggeredHandlers.put(callback, NULL_MAP);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use Map.of()? We want that map to be immutable anyways.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't think about it. It makes much more sense. Done, thanks.

private final IdentityHashMap<Object, Set<Object>> activeHandlers = new IdentityHashMap<>();
private final IdentityHashMap<Object, Map<Object, Set<Object>>> triggeredHandlers = new IdentityHashMap<>();
private static final Map<Object, Set<Object>> NULL_MAP = new IdentityHashMap<>();
private final ConcurrentIdentityHashMap<Object, ConcurrentHashMap.KeySetView<Object, Boolean>> activeHandlers = new ConcurrentIdentityHashMap<>();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why change the generic type from Set to ConcurrentHashMap.KeySetView? The field can just be defined as Map<Object, Set<Object>> activeHandlers.

Same for all the other type definitions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I just like explicit types :)

Changed.

@@ -88,7 +91,7 @@ private void registerReachabilityHandler(BeforeAnalysisAccess a, Object callback
BeforeAnalysisAccessImpl access = (BeforeAnalysisAccessImpl) a;
AnalysisMetaAccess metaAccess = access.getMetaAccess();

Set<Object> triggerSet = activeHandlers.computeIfAbsent(callback, c -> new HashSet<>());
ConcurrentHashMap.KeySetView<Object, Boolean> triggerSet = activeHandlers.computeIfAbsent(callback, c -> ConcurrentHashMap.newKeySet());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's actually the prototypical use case for var triggerSet, which we can now use in the native-image code base.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Prevent data races in reachability handlers registration when using
`-H:-RunReachabilityHandlersConcurrently`.

Closes oracle#5868
@zakkak zakkak force-pushed the 2023-11-06-fix-5868 branch from c4f2371 to 777cb82 Compare November 9, 2023 08:40
@christianwimmer
Copy link

@oubidar-Abderrahim can you please create the internal PR for this

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 9, 2023

Thank you for the review @christianwimmer

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 9, 2023

This should also be backported to 23.1 and 23.0

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 22, 2023

@oubidar-Abderrahim is there any progress in regards to getting this merged? Thanks

@christianwimmer
Copy link

@oubidar-Abderrahim is there any progress in regards to getting this merged? Thanks

I'm in the process of running the final tests and benchmarks, should be merged soon. And it will be backported.

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 22, 2023

Great, thanks for the update @christianwimmer.

@graalvmbot graalvmbot merged commit ca91228 into oracle:master Nov 24, 2023
12 checks passed
@zakkak zakkak deleted the 2023-11-06-fix-5868 branch November 24, 2023 12:09
@btomala
Copy link

btomala commented Nov 29, 2023

We encountered the same issue. Thanks for fixing it. @christianwimmer when do we expect this will be released?

@zakkak
Copy link
Collaborator Author

zakkak commented Nov 29, 2023

@btomala it should land in GraalVM for JDK 21.0.2 in late January.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Verified All contributors have signed the Oracle Contributor Agreement. redhat-interest
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[GR-44056] Cannot invoke "java.util.Set.iterator()" because "triggers" is null.
4 participants