From efc2fcb2a9c804b195f47763995d8622a0dd4990 Mon Sep 17 00:00:00 2001 From: Manuel Laubach Date: Thu, 29 Sep 2022 15:18:31 +0200 Subject: [PATCH] philosophers are fed --- src/main/kotlin/DiningPhilosophers.kt | 37 ++++++++++++++++++++--- src/test/kotlin/DiningPhilosophersTest.kt | 5 ++- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/DiningPhilosophers.kt b/src/main/kotlin/DiningPhilosophers.kt index 24a579f..dba72e7 100644 --- a/src/main/kotlin/DiningPhilosophers.kt +++ b/src/main/kotlin/DiningPhilosophers.kt @@ -1,11 +1,13 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.sync.Mutex class Fork(id: String) : Observable(id) { //TODO // --------------- EDIT CODE BELOW --------------- + val mutex = Mutex() suspend fun take(philosopher: String) { setOccupiedBy(philosopher) @@ -13,6 +15,7 @@ class Fork(id: String) : Observable(id) { suspend fun release() { setOccupiedBy(null) + mutex.unlock() } // --------------- EDIT CODE ABOVE --------------- @@ -33,20 +36,46 @@ class Philosopher( private val leftFork: Fork, private val rightFork: Fork, ) : Observable(id) { - //TODO // --------------- EDIT CODE BELOW --------------- suspend fun start() = repeat(10) { + think() + while (true) { + if (leftFork.mutex.tryLock(id) && rightFork.mutex.tryLock(id)) { + takeForks() + break + } else { + println("phil $id has left fork locked : ${leftFork.mutex.isLocked}") + println("phil $id has right fork locked : ${rightFork.mutex.isLocked}") + if (leftFork.mutex.holdsLock(id)) { + leftFork.mutex.unlock(id) + } + if (rightFork.mutex.holdsLock(id)) { + rightFork.mutex.unlock(id) + } + wait() + } + } - }.also { changeState("FINISHED") } + eat() + releaseForksAndUnlock() + }.also { + changeState("FINISHED") + } private suspend fun takeForks() { leftFork.take(id) rightFork.take(id) + println("phil $id has taken forks") + } + private suspend fun releaseForksAndUnlock() { + leftFork.release() + rightFork.release() + println("phil $id has released forks") } - // --------------- EDIT CODE ABOVE --------------- +// --------------- EDIT CODE ABOVE --------------- private suspend fun wait() { delay(1) @@ -94,7 +123,7 @@ suspend fun main(args: Array) = runBlocking { } forks.forEach { it.onChange = { fork, philosopher -> - println(philosopher?.let { "$fork acquired by $it" } ?: "$fork released") + println(philosopher?.let { "$philosopher $fork acquired by $it" } ?: "$philosopher $fork released") } } diff --git a/src/test/kotlin/DiningPhilosophersTest.kt b/src/test/kotlin/DiningPhilosophersTest.kt index f40ef58..8c2c3ae 100644 --- a/src/test/kotlin/DiningPhilosophersTest.kt +++ b/src/test/kotlin/DiningPhilosophersTest.kt @@ -20,7 +20,6 @@ class DiningPhilosophersTest : StringSpec() { init { coroutineDebugProbes = true - timeout = 2000 val philosopherNumbers = listOf(2, 5, 12).exhaustive() @@ -59,13 +58,13 @@ class DiningPhilosophersTest : StringSpec() { diningPhilosopherLogger.send(ReadLogMessage(response)) response.await() - .filter { it.first.contains("Philosophers") } + .filter { it.first.contains("Philosopher") } .filter { it.second == "THINKING" } .groupBy { it.first } .apply { size shouldBe n forEach { - it.value.size shouldBe n + it.value.size shouldBe 10 } }