Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
/fixes #9093 /claim #9093
Rewrite Semaphore to use a single AtomicLong instead of a Ref[Either[Queue, Long]].
The old implementation used an immutable Scala queue inside a Ref to track waiters. Every acquire/release went through ref.modify, which meant allocating new queue instances and ZIO effects even on the happy path.
The new implementation packs permit/waiter state into a single AtomicLong
The new implementation uses a MutableConcurrentQueue for pending waiters instead of copying immutable queues, though this could be changed for a more performant queue later.
The new
Waitertrait is used to represent waiters requiring a single permit and multiple permits. This prevents allocating an AtomicLong per waiter in the most common case.Benchmarks show a 30-100% performance improvement. See benchmarks here: https://jmh.morethan.io/?gists=5889786ef8c51621de513da9ec45091d,1b73e3a975d46b09f92936c30e3b83cb