zeolite-lang-0.22.1.0: tests/leak-check/leak-check.0rx
concrete LeakTest {
@type run () -> ()
}
define LeakTest {
@value Vector<Int> memory
run () {
if (Argv.global().size() != 2) {
\ message()
} elif (Argv.global().readAt(1) == "race") {
\ runWith(1000,0)
\ BasicOutput.stderr().writeNow("no race conditions this time\n")
} elif (Argv.global().readAt(1) == "leak") {
\ runWith(100,0)
} elif (Argv.global().readAt(1) == "forever") {
\ runWith(10000000,1024*1024)
} else {
\ message()
}
}
@type message () -> ()
message () {
fail(Argv.global().readAt(0) + " [race|leak|forever]")
}
@type runWith (Int,Int) -> ()
runWith (iterations,size) {
Int threads <- Ranges:max(3,$ExprLookup[CPU_CORE_COUNT]$-1)
ReadAt<BarrierWait> barriers <- EnumeratedBarrier.new(threads+1)
traverse (Counter.zeroIndexed(iterations) -> Int i) {
\ doIteration<LastReference>(i,size,barriers)
\ doIteration<Chaos>(i,size,barriers)
}
}
@type doIteration<#f>
#f defines ThreadFactory
(Int,Int,ReadAt<BarrierWait>) -> ()
doIteration (i,size,barriers) {
\ BasicOutput.stderr()
.write(typename<#f>())
.write(": iteration ")
.write(i)
.write("\n")
.flush()
optional LeakTest original <- LeakTest{ Vector:createSize<Int>(size) }
weak LeakTest checkedValue <- original
$ReadOnly[checkedValue]$
scoped {
Vector<Thread> threads <- Vector<Thread>.new()
} in {
traverse (Counter.zeroIndexed(barriers.size()-1) -> Int j) {
\ threads.push(ProcessThread.from(#f.create(original,barriers.readAt(j+1))).start())
}
\ barriers.readAt(0).wait()
original <- empty
traverse (threads.defaultOrder() -> Thread thread) {
\ thread.join()
}
}
// Make sure that threads are out of scope before validating.
$ValidateRefs[checkedValue]$
}
}
@type interface ThreadFactory {
create (optional LeakTest,BarrierWait) -> (Routine)
}
concrete LastReference {
defines ThreadFactory
}
define LastReference {
$ReadOnlyExcept[]$
refines Routine
@value weak LeakTest copy
@value BarrierWait barrier
create (copy,barrier) {
return LastReference{ copy, barrier }
}
run () {
\ barrier.wait()
\ strong(copy)
}
}
concrete Chaos {
defines ThreadFactory
}
define Chaos {
$ReadOnly[barrier]$
refines Routine
@value weak LeakTest copy
@value BarrierWait barrier
create (copy,barrier) {
return Chaos{ copy, barrier }
}
run () {
weak LeakTest copy1 <- empty
weak LeakTest copy2 <- empty
weak LeakTest copy3 <- empty
weak LeakTest copy4 <- empty
weak LeakTest copy5 <- empty
\ barrier.wait()
copy1 <- copy
copy2 <- copy1
copy3 <- copy1
copy <- empty
copy4 <- strong(copy2)
copy1 <- strong(copy3)
copy2 <- empty
copy3 <- empty
}
}