Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add simple validation to the philosophers benchmark #446

Merged
merged 2 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import org.renaissance.Benchmark
import org.renaissance.Benchmark._
import org.renaissance.BenchmarkContext
import org.renaissance.BenchmarkResult
import org.renaissance.BenchmarkResult.Validators
import org.renaissance.BenchmarkResult.Assert
import org.renaissance.License

@Name("philosophers")
Expand Down Expand Up @@ -33,17 +33,29 @@ final class Philosophers extends Benchmark {
*/
private var mealCountParam: Int = _

override def setUpBeforeAll(c: BenchmarkContext) = {
override def setUpBeforeAll(c: BenchmarkContext): Unit = {
threadCountParam = c.parameter("thread_count").toPositiveInteger
mealCountParam = c.parameter("meal_count").toPositiveInteger
}

private def validate(forkOwners: Seq[Option[String]], mealsEaten: Seq[Int]): Unit = {
// All forks should be available, i.e., not owned by anyone.
for (i <- 0 until threadCountParam) {
Assert.assertEquals(None, forkOwners(i), s"owner of fork %i")
}

// All philosophers should have eaten the expected number of meals.
for (i <- 0 until threadCountParam) {
Assert.assertEquals(mealCountParam, mealsEaten(i), s"meals eaten by philosopher $i")
}
}

override def run(c: BenchmarkContext): BenchmarkResult = {
// TODO: Return something useful, not elapsed time
RealityShowPhilosophers.run(mealCountParam, threadCountParam)
val (forkOwners, mealsEaten) = RealityShowPhilosophers.run(mealCountParam, threadCountParam)

// TODO: add proper validation
Validators.dummy()
() => {
validate(forkOwners, mealsEaten)
}
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.renaissance.scala.stm

import scala.annotation.tailrec
import scala.collection._
import scala.collection.mutable
import scala.concurrent.stm._

/**
Expand Down Expand Up @@ -85,27 +85,23 @@ object RealityShowPhilosophers {
}
}

def time(philosopherCount: Int, meals: Int): Long = {
def run(mealCount: Int, philosopherCount: Int): (Seq[Option[String]], Seq[Int]) = {
val names = for (i <- 0 until philosopherCount) yield {
s"philosopher-$i"
}
val forks = Array.tabulate(names.size) { _ =>
new Fork
}
val pthreads = Array.tabulate(names.size) { i =>
new PhilosopherThread(names(i), meals, forks(i), forks((i + 1) % forks.length))
new PhilosopherThread(names(i), mealCount, forks(i), forks((i + 1) % forks.length))
}
val camera = new CameraThread(1000 / 60, forks, pthreads)
val start = System.currentTimeMillis
camera.start()
for (t <- pthreads) t.start()
for (t <- pthreads) t.join()
val elapsed = System.currentTimeMillis - start
camera.join()
elapsed
}

def run(meals: Int, philosopherCount: Int) = {
time(philosopherCount, meals)
atomic { implicit txn =>
(forks.map(_.owner.get), pthreads.map(_.mealsEaten.get))
}
}
}