Skip to content

Non-linearizable return value of put operation in NonBlockingHashMapLong #319

@alefedor

Description

@alefedor

There is a bug in jctools 3.1 that results in NonBlockingHashMapLong.put returning not the previous value, but the next one added in a concurrent thread.

The bug can be reproduced with Lincheck.
The scenario with incorrect results has two parallel threads with one operation each, and one operation after the threads are finished:

Parallel part:
| put(5, -2): null | put(5, -8): -2 |
Post part:
[get(5): -2]

If put(5, -8) returned -2, then the result of the next get should have been -8.

There was the same bug in jctools 2.1 for NonBlockingHashMap, which seem to be fixed.

In case the reasons of the bug differ from NonBlockingHashMap, I also attach the trace with only two context switches that leads to non-linearizable results (yet to be released feature in Lincheck).

= Parallel part execution: =
|                      | put(5, -8)                                                                                            |
|                      |   _chm.READ: @313a67ba at NonBlockingHashMapLong.putIfMatch(NonBlockingHashMapLong.java:316)          |
|                      |   READ: null at NonBlockingHashMapLong$CHM.putIfMatch(NonBlockingHashMapLong.java:559)                |
|                      |   switch                                                                                              |
| put(5, -2): null     |                                                                                                       |
|   thread is finished |                                                                                                       |
|                      |   READ: null at NonBlockingHashMapLong$CHM.putIfMatch(NonBlockingHashMapLong.java:560)                |
|                      |   CAS_val(5,null,-8): false at NonBlockingHashMapLong$CHM.putIfMatch(NonBlockingHashMapLong.java:641) |
|                      |   READ: null at NonBlockingHashMapLong$CHM.putIfMatch(NonBlockingHashMapLong.java:651)                |
|                      |   result: -2                                                                                          |
|                      |   thread is finished                                                                                  |

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions