Skip to content

Commit

Permalink
First cut of dining philosophers
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrey Paramonov committed Oct 7, 2012
1 parent 6acbc07 commit 9566196
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/dojo/philosophers.clj
@@ -0,0 +1,35 @@
;; http://en.wikipedia.org/wiki/Dining_philosophers_problem

(ns dojo.philosophers)

(defn forks [n] (mapv ref (repeat n 0)))

(defn enjoy-meal [] (Thread/sleep (rand-int 500)))

(defn eat [phil forks]
(let [place (map #(mod % (count forks)) [phil (inc phil)])]
(dosync
(alter (forks (first place)) inc) ; grab right fork
(alter (forks (second place)) inc) ; grab left fork
(enjoy-meal))))

(defn log [thread & message]
(println (System/currentTimeMillis) ":" (inc thread) message))

(defn think [] (Thread/sleep (rand-int 500)))

(defn philosopher [id meals forks]
(dotimes [m meals]
(log id "thinking")
(think)
(log id "hungry")
(eat id forks)
(log id "ate" (inc m) "meal")))

(defn dine
([people meals]
(dine people meals (forks people)))
([people meals forks]
(let [threads (map (fn [id] #(philosopher id meals forks)) (range people))]
(dorun (apply pcalls threads)))))

21 changes: 21 additions & 0 deletions test/dojo/philosophers_test.clj
@@ -0,0 +1,21 @@
(ns dojo.philosophers-test
(:use clojure.test
dojo.philosophers))

(deftest eat-test
(let [forks (forks 5)]
(eat 0 forks)
(is (= [1 1 0 0 0] (mapv deref forks)))
(eat 1 forks)
(is (= [1 2 1 0 0] (mapv deref forks)))))

(comment deftest philosopher-test
(let [forks (forks 5)]
(philosopher 0 7 forks)
(is (= [7 7 0 0 0] (mapv deref forks)))))

(deftest dine-test
(let [forks (forks 5)]
(dine 5 3 forks)
(is (= [6 6 6 6 6] (mapv deref forks)))))

0 comments on commit 9566196

Please sign in to comment.