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

Fixes issue366 #367

Merged
merged 6 commits into from
Feb 23, 2021
Merged

Fixes issue366 #367

merged 6 commits into from
Feb 23, 2021

Conversation

RalphSteinhagen
Copy link
Member

No description provided.

@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:05 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:05 Inactive
@restyled-io restyled-io bot mentioned this pull request Feb 18, 2021
@codecov
Copy link

codecov bot commented Feb 18, 2021

Codecov Report

Merging #367 (e0a2e9f) into master (a3ef489) will increase coverage by 0.02%.
The diff coverage is 69.23%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #367      +/-   ##
============================================
+ Coverage     52.05%   52.08%   +0.02%     
- Complexity     7150     7155       +5     
============================================
  Files           383      383              
  Lines         40270    40269       -1     
  Branches       6504     6506       +2     
============================================
+ Hits          20964    20975      +11     
+ Misses        17796    17782      -14     
- Partials       1510     1512       +2     
Impacted Files Coverage Δ Complexity Δ
.../java/de/gsi/dataset/locks/DefaultDataSetLock.java 60.21% <60.97%> (+1.26%) 18.00 <10.00> (+1.00)
...rtfx-chart/src/main/java/de/gsi/chart/XYChart.java 74.03% <100.00%> (+0.14%) 62.00 <9.00> (+1.00)
...hart/plugins/measurements/DataSetMeasurements.java 75.43% <0.00%> (-0.35%) 151.00% <0.00%> (-2.00%)
...main/java/de/gsi/chart/ui/HiddenSidesPaneSkin.java 44.97% <0.00%> (+0.47%) 36.00% <0.00%> (+1.00%)
...ataset/src/main/java/de/gsi/dataset/DataSet2D.java 12.50% <0.00%> (+12.50%) 1.00% <0.00%> (+1.00%)
...si/chart/axes/spi/format/DefaultTimeFormatter.java 79.16% <0.00%> (+20.83%) 13.00% <0.00%> (+2.00%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a3ef489...e0a2e9f. Read the comment docs.

@RalphSteinhagen RalphSteinhagen temporarily deployed to deploy February 18, 2021 20:09 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:12 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:12 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:12 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:15 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:15 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:15 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 18, 2021 20:15 Inactive
@RalphSteinhagen RalphSteinhagen linked an issue Feb 18, 2021 that may be closed by this pull request
@RalphSteinhagen RalphSteinhagen temporarily deployed to deploy February 18, 2021 20:25 Inactive
@RalphSteinhagen RalphSteinhagen marked this pull request as ready for review February 18, 2021 20:25
@RalphSteinhagen RalphSteinhagen temporarily deployed to deploy February 18, 2021 20:25 Inactive
Copy link
Collaborator

@ennerf ennerf left a comment

Choose a reason for hiding this comment

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

Without having done a deep analysis of the locking, the logic looks correct. I ran the test on a 12/24 cpu with various combinations and could not make it fail.

The synchronized blocks are however worrying, and the performance is quite a bit worse. I uploaded a video of comparing this PR (left) to 11.2.5 (right):

chart-fx #367

The calculator shows how often the same plot is open on both versions. Each plot has 3x 6k points coming in at about ~640 Hz.

N.B. read(Un)Lock(..) still works but its use should be deprecated compared to the lock guards due to worse performance
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 21, 2021 11:49 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 21, 2021 11:49 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 21, 2021 11:49 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to deploy February 21, 2021 11:58 Inactive
…k(..)

N.B. avoids dead-lock
de.gsi.chart.samples.legacy.ChartHighUpdateRateSample is a good test-case to reproduce the write-race-condition and prove of the dead-lock.
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 21, 2021 20:24 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 21, 2021 20:24 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 21, 2021 20:24 Inactive
@RalphSteinhagen
Copy link
Member Author

@ennerf thanks for your follow-up. I could reproduce your observation using the example 'de.gsi.chart.samples.legacy.ChartHighUpdateRateSample' which updates the DataSet @1KHz (N.B. in-build Chart-fx rate-limiter limits this to <50Hz).

replaced writeLock() internally with spinning StampedLock:tryWriteLock(..) the unit-tests and sample seem to work (for my part) but would be nice to see whether your use-case is still OK.

N.B. avoids dead-lock
de.gsi.chart.samples.legacy.ChartHighUpdateRateSample is a good test-case to reproduce the write-race-condition and prove of the dead-lock.

@RalphSteinhagen RalphSteinhagen temporarily deployed to deploy February 21, 2021 20:34 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 21, 2021 20:35 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 21, 2021 20:35 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to deploy February 21, 2021 20:45 Inactive
@ennerf
Copy link
Collaborator

ennerf commented Feb 22, 2021

The performance is maybe slightly better than with the first fix, but it's tough to tell visually. Still noticably worse than pre-fix.

@RalphSteinhagen
Copy link
Member Author

@ennerf based on the stress tests the max write-lock frequency is now around 2-3 kHz...

In your example: how many writer/readers and update/read rates do you typically have?

Presently -- apart from getting the Thread.currentThread() -- it's pretty much bare StampedLock performance. The only (remaining) difference is that the readLock is now done locally and without AtomicInteger read-counter that are more efficient but cause the read lock/unlock race....

Have to think about whether one can still use atomics and only use the stampedLock.readLock() only for the first/critical reader...

@ennerf
Copy link
Collaborator

ennerf commented Feb 22, 2021

1 writer + 1x UI thread reader w/ the concurrent rendering parts. The update rate for each plot is 1-4 x 0.1-1KHz.

@RalphSteinhagen
Copy link
Member Author

I'll give it another try with atomics-only ...

@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 22, 2021 11:44 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 22, 2021 11:44 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 22, 2021 11:44 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 22, 2021 11:44 Inactive
@RalphSteinhagen
Copy link
Member Author

modified read-lock and re-introduced atomic guards

only the first reader acquires a lock, subsequent readers increase atomic counter, and only the last remaining reader unlocks.

detects race-condition on initial lock and final unlock

only the first reader acquires a lock, subsequent readers increase atomic counter, and only the last remaining reader unlocks.

detects race-condition on initial lock and final unlock
@RalphSteinhagen RalphSteinhagen temporarily deployed to deploy February 22, 2021 11:54 Inactive
@RalphSteinhagen RalphSteinhagen temporarily deployed to deploy February 22, 2021 11:54 Inactive
@ennerf ennerf self-requested a review February 23, 2021 09:52
private transient Thread writeLockedByThread; // NOPMD
private final transient AtomicInteger readerCount = new AtomicInteger(0);
private final transient AtomicInteger writerCount = new AtomicInteger(0);
private final AtomicLong lastReadStamp = new AtomicLong(-1L);
Copy link
Collaborator

@ennerf ennerf Feb 23, 2021

Choose a reason for hiding this comment

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

should these fields still be transient?

@dedeibel
Copy link
Contributor

I observed no more test failures with this version and could not see of any loopholes at the moment. Thanks.

@RalphSteinhagen RalphSteinhagen merged commit b039e76 into master Feb 23, 2021
@RalphSteinhagen RalphSteinhagen deleted the fixIssue366 branch February 23, 2021 14:09
@RalphSteinhagen RalphSteinhagen temporarily deployed to coverage February 23, 2021 18:59 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Problem with DefaultDataSetLock
3 participants