lean4-htt/tests/lean/run/sync_barrier.lean
Paul Reichert 98e4b2882f
refactor: migrate to new ranges (#8841)
This PR migrates usages of `Std.Range` to the new polymorphic ranges.

This PR unfortunately increases the transitive imports for
frequently-used parts of `Init` because the ranges now rely on iterators
in order to provide their functionality for types other than `Nat`.
However, iteration over ranges in compiled code is as efficient as
before in the examples I checked. This is because of a special
`IteratorLoop` implementation provided in the PR for this purpose.

There were two issues that were uncovered during migration:

* In `IndPredBelow.lean`, migrating the last remaining range causes
`compilerTest1.lean` to break. I have minimized the issue and came to
the conclusion it's a compiler bug. Therefore, I have not replaced said
old range usage yet (see #9186).
* In `BRecOn.lean`, we are publicly importing the ranges. Making this
import private should theoretically work, but there seems to be a
problem with the module system, causing the build to panic later in
`Init.Data.Grind.Poly` (see #9185).
* In `FuzzyMatching.lean`, inlining fails with the new ranges, which
would have led to significant slowdown. Therefore, I have not migrated
this file either.
2025-07-07 12:41:53 +00:00

32 lines
1.1 KiB
Text

import Std.Sync.Barrier
def consBarrier (b : Std.Barrier) (list : IO.Ref (List Nat)) : IO Bool := do
for _ in *...(1000 : Nat) do
list.modify fun l => 1 :: l
let isLeader ← b.wait
for _ in *...(1000 : Nat) do
list.modify fun l => 2 :: l
return isLeader
def barrier : IO Unit := do
let b ← Std.Barrier.new 2
let ref ← IO.mkRef []
go b ref
-- reuse barrier
go b ref
where
go (b : Std.Barrier) (ref : IO.Ref (List Nat)) : IO Unit := do
let t1 ← IO.asTask (prio := .dedicated) (consBarrier b ref)
let t2 ← IO.asTask (prio := .dedicated) (consBarrier b ref)
let leaderT1 ← IO.ofExcept t1.get
let leaderT2 ← IO.ofExcept t2.get
if leaderT1 == leaderT2 then
let err := s!"Exactly one should be leader but t1 leader? {leaderT1} t2 leader? {leaderT2}"
throw <| .userError err
let list ← ref.get
if list.take 2000 |>.any (· != 2) then
throw <| .userError "List head should have only 2's but doesn't"
if list.drop 2000 |>.take 2000 |>.any (· != 1) then
throw <| .userError "List tail should have only 1's but doesn't"
#eval barrier