about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--mu.arc5
-rw-r--r--mu.arc.t27
2 files changed, 27 insertions, 5 deletions
diff --git a/mu.arc b/mu.arc
index 0c6ea313..88b8669c 100644
--- a/mu.arc
+++ b/mu.arc
@@ -253,7 +253,8 @@
       (let next-wakeup-cycle (apply min (map [rep._!sleep 0] exact-sleeping-routines))
         (= curr-cycle* (+ 1 next-wakeup-cycle))
         (trace "schedule" "skipping to cycle " curr-cycle*)
-        (update-scheduler-state)))))
+        (update-scheduler-state))))
+  (detect-deadlock))
 
 (def detect-deadlock ()
   (when (and empty.running-routines*
@@ -262,7 +263,7 @@
     (each (routine _) sleeping-routines*
       (wipe sleeping-routines*.routine)
       (= rep.routine!error "deadlock detected")
-      (enq routine completed-routines*))))
+      (push routine completed-routines*))))
 
 (def die (msg)
   (= rep.routine*!error msg)
diff --git a/mu.arc.t b/mu.arc.t
index da0ffa0f..685e097e 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -1773,7 +1773,7 @@
 ; add one baseline routine to run (empty running-routines* handled below)
 (enq make-routine!f1 running-routines*)
 (assert (is 1 len.running-routines*))
-; sleeping routine
+; blocked routine
 (let routine make-routine!f2
   (= rep.routine!sleep '(23 integer))
   (set sleeping-routines*.routine))
@@ -1801,11 +1801,11 @@
 ; add one baseline routine to run (empty running-routines* handled below)
 (enq make-routine!f1 running-routines*)
 (assert (is 1 len.running-routines*))
-; sleeping routine
+; blocked routine
 (let routine make-routine!f2
   (= rep.routine!sleep '(23 integer))
   (set sleeping-routines*.routine))
-; set memory location
+; set memory location and unblock routine
 (= memory*.23 1)
 (update-scheduler-state)
 (if (~is 2 len.running-routines*)
@@ -1830,6 +1830,27 @@
   (prn "F - scheduler skips ahead to earliest sleeping routines when nothing to run"))
 
 (reset)
+(new-trace "scheduler-deadlock")
+(add-fns
+  '((f1
+      ((1 integer) <- copy (3 literal)))))
+(assert (empty running-routines*))
+(assert (empty completed-routines*))
+; blocked routine
+(let routine make-routine!f1
+  (= rep.routine!sleep '(23 integer))
+  (set sleeping-routines*.routine))
+; location it's waiting on is 'empty'
+(= memory*.23 0)
+(update-scheduler-state)
+(assert (~empty completed-routines*))
+;? (prn completed-routines*)
+(let routine completed-routines*.0
+  (when (~posmatch "deadlock" rep.routine!error)
+    (prn "F - scheduler detects deadlock")))
+;? (quit)
+
+(reset)
 (new-trace "sleep")
 (add-fns
   '((f1