From 3d774b31e8cd3b89ff26567c8c3636bd17663adb Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Tue, 12 Dec 2023 13:21:59 +0100 Subject: [PATCH 1/5] Update scala-native dependencies - Move scala-native pinned version to latest main commit - Remove munit loop patch as it has been reverted on scala-native - Immix GC might work now --- build.sbt | 43 ++++++++++++++++++++++----------------- dependencies/munit | 2 +- dependencies/scala-native | 2 +- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/build.sbt b/build.sbt index 52bd51f2..8294ba42 100644 --- a/build.sbt +++ b/build.sbt @@ -5,22 +5,27 @@ ThisBuild / scalaVersion := "3.3.1" lazy val root = crossProject(JVMPlatform, NativePlatform) - .crossType(CrossType.Full) - .in(file(".")) - .settings(Seq( - name := "Gears", - organization := "ch.epfl.lamp", - version := "0.1.0-SNAPSHOT", - testFrameworks += new TestFramework("munit.Framework") - )) - .jvmSettings(Seq( - javaOptions += "--version 21", - libraryDependencies += "org.scalameta" %% "munit" % "1.0.0-M10" % Test - )) - .nativeSettings(Seq( - nativeConfig ~= { c => - c.withMultithreadingSupport(true) - .withGC(GC.boehm) // immix doesn't work yet - }, - libraryDependencies += "org.scalameta" %%% "munit" % "1.0.0-M10+15-3940023e-SNAPSHOT" % Test - )) + .crossType(CrossType.Full) + .in(file(".")) + .settings( + Seq( + name := "Gears", + organization := "ch.epfl.lamp", + version := "0.1.0-SNAPSHOT", + testFrameworks += new TestFramework("munit.Framework") + ) + ) + .jvmSettings( + Seq( + javaOptions += "--version 21", + libraryDependencies += "org.scalameta" %% "munit" % "1.0.0-M10" % Test + ) + ) + .nativeSettings( + Seq( + nativeConfig ~= { c => + c.withMultithreadingSupport(true) + }, + libraryDependencies += "org.scalameta" %%% "munit" % "1.0.0-M10+15-3940023e-SNAPSHOT" % Test + ) + ) diff --git a/dependencies/munit b/dependencies/munit index 3940023e..4e2ab919 160000 --- a/dependencies/munit +++ b/dependencies/munit @@ -1 +1 @@ -Subproject commit 3940023e5a3c07673611f561b57e043fb9ac51ec +Subproject commit 4e2ab919efd31595ccf0df7cf518655d8d2de40c diff --git a/dependencies/scala-native b/dependencies/scala-native index f4b9078c..20a7ccd0 160000 --- a/dependencies/scala-native +++ b/dependencies/scala-native @@ -1 +1 @@ -Subproject commit f4b9078c6c96dade366518f037d8f47048d2a4f3 +Subproject commit 20a7ccd09db10a34058c7a453dea56c2e00ca712 From c3d1c360c9dd5ab186fc50ff1606ab8c2e53082d Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Tue, 12 Dec 2023 16:34:58 +0100 Subject: [PATCH 2/5] Update snapshot commit of munit in build.sbt --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 8294ba42..21e26900 100644 --- a/build.sbt +++ b/build.sbt @@ -26,6 +26,6 @@ lazy val root = nativeConfig ~= { c => c.withMultithreadingSupport(true) }, - libraryDependencies += "org.scalameta" %%% "munit" % "1.0.0-M10+15-3940023e-SNAPSHOT" % Test + libraryDependencies += "org.scalameta" %%% "munit" % "1.0.0-M10+16-4e2ab919-SNAPSHOT" % Test ) ) From 0f04fbd8c1aaf0641e666acb5be5ed806a1885ba Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Mon, 18 Dec 2023 18:24:14 +0100 Subject: [PATCH 3/5] Add a stress test for creating lots of futures --- .github/workflows/ci.yml | 2 ++ shared/src/test/scala/Stress.scala | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 shared/src/test/scala/Stress.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 55d15ad5..73bf3a11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,3 +85,5 @@ jobs: run: sudo apt-get install clang libstdc++-12-dev libgc-dev - name: Test run: sbt rootNative/test + - name: Stress Test with Lower Memory + run: env GC_MAXIMUM_HEAP_SIZE=64M sbt 'rootNative/testOnly StressTest' diff --git a/shared/src/test/scala/Stress.scala b/shared/src/test/scala/Stress.scala new file mode 100644 index 00000000..f4c5cb03 --- /dev/null +++ b/shared/src/test/scala/Stress.scala @@ -0,0 +1,23 @@ +import gears.async.{Async, Future, AsyncSupport, uninterruptible} +import gears.async.AsyncOperations.* +import gears.async.default.given +import gears.async.Future.MutableCollector +import java.util.concurrent.atomic.AtomicInteger + +class StressTest extends munit.FunSuite: + test("survives a stress test that hammers on creating futures") { + val total = 200_000L + Seq[Long](1, 2, 4, 16, 10000).foreach: parallelism => + val k = AtomicInteger(0) + def compute(using Async) = + k.incrementAndGet() + Async.blocking: + val collector = MutableCollector((1L to parallelism).map(_ => Future { compute })*) + var sum = 0L + for i <- parallelism + 1 to total do + sum += collector.results.read().right.get.await + collector += Future { compute } + for i <- 1L to parallelism do sum += collector.results.read().right.get.await + assertEquals(sum, total * (total + 1) / 2) + + } From 8a3151d7195824b6206c78152996a043179a11c2 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Mon, 18 Dec 2023 19:29:41 +0100 Subject: [PATCH 4/5] Add a stress test for creating lots of suspensions --- .github/workflows/ci.yml | 2 +- shared/src/test/scala/Stress.scala | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73bf3a11..eaa8215b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,4 +86,4 @@ jobs: - name: Test run: sbt rootNative/test - name: Stress Test with Lower Memory - run: env GC_MAXIMUM_HEAP_SIZE=64M sbt 'rootNative/testOnly StressTest' + run: env GC_MAXIMUM_HEAP_SIZE=512M sbt 'rootNative/testOnly StressTest' diff --git a/shared/src/test/scala/Stress.scala b/shared/src/test/scala/Stress.scala index f4c5cb03..ddc71733 100644 --- a/shared/src/test/scala/Stress.scala +++ b/shared/src/test/scala/Stress.scala @@ -3,6 +3,8 @@ import gears.async.AsyncOperations.* import gears.async.default.given import gears.async.Future.MutableCollector import java.util.concurrent.atomic.AtomicInteger +import gears.async.Timer +import scala.concurrent.duration._ class StressTest extends munit.FunSuite: test("survives a stress test that hammers on creating futures") { @@ -19,5 +21,25 @@ class StressTest extends munit.FunSuite: collector += Future { compute } for i <- 1L to parallelism do sum += collector.results.read().right.get.await assertEquals(sum, total * (total + 1) / 2) + } + test("survives a stress test that hammers on suspending") { + val total = 100_000L + val parallelism = 5000L + Async.blocking: + val sleepy = + val timer = Timer(1.second) + Future { timer.run() } + timer.src + val k = AtomicInteger(0) + def compute(using Async) = + sleepy.awaitResult + k.incrementAndGet() + val collector = MutableCollector((1L to parallelism).map(_ => Future { compute })*) + var sum = 0L + for i <- parallelism + 1 to total do + sum += collector.results.read().right.get.await + collector += Future { compute } + for i <- 1L to parallelism do sum += collector.results.read().right.get.await + assertEquals(sum, total * (total + 1) / 2) } From 8e33d12b6ba714b4722cd2fd35372490eb660485 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Fri, 22 Dec 2023 15:21:44 +0100 Subject: [PATCH 5/5] Re-add Boehm GC usage ... to avoid problems with the Immix GC for now. --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index 21e26900..24f3e351 100644 --- a/build.sbt +++ b/build.sbt @@ -25,6 +25,7 @@ lazy val root = Seq( nativeConfig ~= { c => c.withMultithreadingSupport(true) + .withGC(GC.boehm) }, libraryDependencies += "org.scalameta" %%% "munit" % "1.0.0-M10+16-4e2ab919-SNAPSHOT" % Test )