Skip to content

Linearizability tests for concurrent maps and sets#328

Merged
nitsanw merged 3 commits into
JCTools:masterfrom
alefedor:linearizability-tests
Nov 25, 2020
Merged

Linearizability tests for concurrent maps and sets#328
nitsanw merged 3 commits into
JCTools:masterfrom
alefedor:linearizability-tests

Conversation

@alefedor

Copy link
Copy Markdown
Contributor

This pull request adds linearizability tests for concurrent maps and sets, based on Lincheck.
Lincheck tests are written in a declarative style, for which you need only to declare possible concurrent operations in the data structure - Lincheck will generate concurrent scenarios, run them, and verify their results automatically.

The tests help to reproduce the bug in #319 with a trace available for an incorrect execution.

They also expose another bug that NonBlockingIdentityHashMap.replace fails if there were no such key before.
For example, new NonBlockingIdentityHashMap().replace(1, 0); will throw an AssertionError, because of unexpected null value. I have a strong feeling that a TOMBSTONE should have been there instead.

I also found that a size method is not linearizable when a concurrent put operation is in action. But I think that it is a feature rather than a bug, because efficient and linearizable size operation is often difficult to implement, although I haven't found any note in the documentation about the problem.

@alefedor alefedor force-pushed the linearizability-tests branch from a86a160 to 96903f7 Compare November 18, 2020 10:42
@franz1981 franz1981 added the bug label Nov 18, 2020
@nitsanw

nitsanw commented Nov 19, 2020

Copy link
Copy Markdown
Contributor

This looks AWESOME!!! thanks for the contribution, I will have a look at it in the near future and integrate.

@nitsanw nitsanw merged commit 6e79875 into JCTools:master Nov 25, 2020
@nitsanw

nitsanw commented Nov 25, 2020

Copy link
Copy Markdown
Contributor

@alefedor Can you please open "They also expose another bug that NonBlockingIdentityHashMap.replace fails if there were no such key before.
For example, new NonBlockingIdentityHashMap().replace(1, 0); will throw an AssertionError, because of unexpected null value. I have a strong feeling that a TOMBSTONE should have been there instead." as a separate bug? I'm not sure exactly what you mean here.

@alefedor

Copy link
Copy Markdown
Contributor Author

@nitsanw Ok. Opened the issue #330

@ben-manes

Copy link
Copy Markdown

I was curious and tried this test against ConcurrentHashMap, but it fails on JDK16. Any insights on why?

= Invalid execution results =
Init part:
[put(4, 4): null]
Parallel part:
| get(1):    4    | put(1, 4): null |
| remove(1): null | clear():   void |
| get(4):    4    |                 |

@alefedor

alefedor commented Sep 12, 2021

Copy link
Copy Markdown
Contributor Author

Hi @ben-manes !

Nice observation, that's definitely a bug in java.util.concurrent.ConcurrentHashMap.
Sometimes a result of a finishedclear is seen by one read in a parallel thread, but is not seen by the next read.

Deducing from the fact that Lincheck can find this bug in the stress testing mode, but not in the model checking one, I suppose that it is related to weak memory model effects (e.g., missing memory barriers).

@alefedor

Copy link
Copy Markdown
Contributor Author

Okay, it may also be a feature, not a bug

For aggregate operations
such as {@code putAll} and {@code clear}, concurrent retrievals may
reflect insertion or removal of only some entries.

https://github.com/openjdk/jdk/blob/2ee1f96c14b80b63a29445629b1f2e1caf88e075/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java#L92

@ben-manes

ben-manes commented Sep 12, 2021

Copy link
Copy Markdown

Ahh, that helps explain it then because a backport of CHMv7 also fails in a similar fashion. I was curious about adding the checks to Caffeine which has an asMap() view. Maybe you could advise me off thread about what a good test suite would look like?

@alefedor

Copy link
Copy Markdown
Contributor Author

@ben-manes

Maybe you could advise me off thread about what a good test suite would look like?

Yes, sure. Email: afedorov2602@gmail.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants