Skip to content

[core] Introduce Gate and remove Barrier#1480

Open
fwbrasil wants to merge 9 commits intomainfrom
gate
Open

[core] Introduce Gate and remove Barrier#1480
fwbrasil wants to merge 9 commits intomainfrom
gate

Conversation

@fwbrasil
Copy link
Collaborator

@fwbrasil fwbrasil commented Mar 8, 2026

I need an equivalent of Java's Phaser for a project. Instead of introducing a separate primitive, this PR replaces Barrier with Gate, and the features of Phaser are a new type Gate.Dynamic. I find java's naming for these abstractions too opaque so I decided to go with a new one that provides a better mental model.


object Unsafe:

def noop(using frame: Frame, allowUnsafe: AllowUnsafe): Unsafe =
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this be static?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I made it a def to take the Frame and improve error messages but it doesn't seem worth it. I'll update

Comment on lines +590 to +592
if parties == 0 then
// No parties remain, close gate
discard(this.close())
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can skip handling the currentPromise since we expect close() to do so... Which is fine, because we only enter advancePass if we win the CAS.

def join(n: Int)(using Frame): Unit < Sync = Sync.Unsafe.defer(self.join(n))

/** Join the gate and apply an inline continuation, avoiding closure allocation. */
inline def joinWith[B, S](inline f: => B < S)(using Frame): B < (S & Sync) =
Copy link
Collaborator

Choose a reason for hiding this comment

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

Missing the joinN variant, but seems ok

*
* Arrived in low bits means arrive is just `state + 1L` — no bit manipulation. Closed as sign bit means `closed` is just `state < 0`.
*/
private type State = State.Impl
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this due to lack of opacity in the same file?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yep, it'd be nice if scala limited the visibility only to the companion

private def doClose(g: Gate)(using Frame): Unit < Sync =
Sync.Unsafe.defer(discard(g.close())) // Scope cleanup, idempotent

/** Packed AtomicLong layout for Gate/Dynamic.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice design

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.

2 participants