Comments (11)
We should expect require(clearCounter.addAndGet(-callbacks.pack(clearCount)) >= 0)
, right? That bombs for me (with and without this PR).
from cats-effect.
So are we sure this is growing unboundedly? The printlns don't really show that. If you squint, it does kinda look like half-ish is being cleared each time.
from cats-effect.
Yes, half-ish of the total is being cleared each time, but each time the total has doubled in size. You can run my reproducer with a larger replicateA_
value and see.
from cats-effect.
Not each time though. We repeat clearance points several times.
- 1
- 2
- 3
- 3
- 4
- 5
- 6
- 7
- 5
- 6
- 7
- 6
- 7
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 10
- 11
- 12
- 13
- 14
- 15
- 11
- 12
- 13
- 14
- 15
- 12
- 13
- 14
- 15
- 13
- 14
- 15
- 14
- 15
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 19
- 20
- 21
- 22
- 23
It certainly feels like something here is wrong, but I'm not sure if it's a conventional example of unbounded growth.
from cats-effect.
You're right, it's not each time, sorry. Every time we pack()
we "lose" 1. So to move up to the next power of 2, first we have to "lose" that many.
from cats-effect.
Ah I see what you're pointing out. Okay gotcha. I'm surprised the off by one fix doesn't correct it then…
from cats-effect.
@mernst-github would you be able to post a self-contained reproducer somewhere? Thanks!
from cats-effect.
- same repro as in #3359
- your fix
- printing the result of
clearCounter.addAndGet
if != 0
I can see the printed values gradually plunge into negative territory.
JDK 17.0.9 and 21.0.1, macOS / AArch64 and Linux / x64.
from cats-effect.
@mernst-github thanks, I tried that before, but I was unable to replicate your result, I probably did something wrong/different. A self-contained reproducer would help a lot :) e.g. a branch of CE with your reproducer in the example
project, with the println
added.
from cats-effect.
If I'm not mistaken the 'pack' logic can overcount when called concurrently, since it may clear the same cell twice, for example like so:
CBS: root -> c1(SET) -> c2(CLEARED) -> null
T1: c1.packInternal(bound, 0, root)
T1: c1 not cleared, call c2.packInternal(bound-1, 0, c1)
~~~context switch~~~~~
<now c1 gets cleared>
T2: c1.packInternal(bound, 0, root)
T2: c1 cleared => root.CAS(c1, c2), call c2.packInternal(bound, 1, root)
CBS: root ----> c2(CLEARED) -> null
c1 (CLEARED) /
~~~context switch~~~~~
T1 resumes @ c2.packInternal(bound-1, 0, c1)
T1: c2 cleared => c1.CAS(c2, null)
CBS: root -> c2(CLEARED) -> null
c1 (CLEARED) -> null
T1: return 1
~~~context switch~~~~~
T2 resumes @ c2.packInternal(bound, 1, root)
T2: c2 cleared => root.CAS(c2, null)
CBS: root -> null
T2: return 2
=> 2 cells cleared, but c2 got double-counted => clearCounter decremented by 3
from cats-effect.
Thanks, you're right! I was able to capture it in a test in 6e2e87d, tracking in #3940.
from cats-effect.
Related Issues (20)
- dispatcher document warning about bounded queue
- sequential dispatcher: race condition in release `step` causes disorder
- Delaying a task to be run far into the future can prevent concurrently scheduled tasks from running HOT 3
- Document stack-safety requirements of typeclasses
- `Dispatcher#unsafeRunTimed` should also `cancel()` if `Await.result` is `interrupt`ed HOT 7
- Flakiness in `SchedulerSpec` HOT 1
- Flakiness in `SupervisorSpec` HOT 1
- Dispatcher sequential runs queued tasks concurrently when closing HOT 2
- Flakiness in `IOSpec` HOT 1
- better handling of callbacks that might throw in `CallbackStack` HOT 1
- Allow overriding how fatal errors are printed HOT 7
- Improve `MonadCancel` scaladoc HOT 4
- Cancelling `Async` queue `take` makes other `take` hang HOT 5
- `IO#asyncCheckAttempt` is inconsistent with `Async#asyncCheckAttempt`
- Improve contributor documentation HOT 3
- Add (best-effort) stealing API to polling system
- Add API to polling system to attempt to get current poller without shifting HOT 6
- More efficient monitoring of fibers on virtual threads HOT 1
- Published tutorial older than tutorial.md HOT 1
- OutOfMemoryError when IO.uncancelable is used in recursive function HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cats-effect.