about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-01-12 00:04:48 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-01-12 00:04:48 -0800
commitf72a25ef728e2cd3d2dd98e6822598f42d4c1b89 (patch)
tree63ad99db4d7868085b5c459208b702f141c35f95
parentf1748ef3479cab9766052514df5f9534db077d70 (diff)
downloadmu-f72a25ef728e2cd3d2dd98e6822598f42d4c1b89.tar.gz
542
Tests for terminating when there's just helpers left.
-rw-r--r--mu.arc26
-rw-r--r--mu.arc.t52
2 files changed, 75 insertions, 3 deletions
diff --git a/mu.arc b/mu.arc
index 94de4148..f8277029 100644
--- a/mu.arc
+++ b/mu.arc
@@ -107,6 +107,19 @@
   (each (expected-label expected-msg)  expected-contents
     (prn "  ! " expected-label ": " expected-msg)))
 
+(def check-trace-doesnt-contain (msg (label unexpected-contents))
+  (when (some (fn ((l s))
+                (and (is l label)  (posmatch unexpected-contents msg)))
+              (as cons traces*))
+    (prn "F - " msg)
+    (prn "  trace contents")
+    (each (l msg) (as cons traces*)
+      (if (and (is l label)
+               (posmatch unexpected-contents msg))
+        (pr "  X ")
+        (pr "    "))
+      (pr label ": " msg))))
+
 ;; virtual machine state
 
 ; things that a future assembler will need separate memory for:
@@ -304,6 +317,7 @@
 ;   add routine* to either running-routines* or sleeping-routines* or completed-routines*
 ;   wake up any necessary sleeping routines (which might be waiting for a
 ;     particular time or for a particular memory location to change)
+;   detect termination: all non-helper routines completed
 ;   detect deadlock: kill all sleeping routines when none can be woken
 (def update-scheduler-state ()
 ;?   (tr curr-cycle*)
@@ -359,12 +373,18 @@
         (= curr-cycle* (+ 1 next-wakeup-cycle)))
       (trace "schedule" "skipping to cycle " curr-cycle*)
       (update-scheduler-state)))
-  (when (and (all [rep._ 'helper] (as cons running-routines*))
+;?   (prn running-routines*)
+;?   (prn sleeping-routines*)
+  (when (and (or (~empty running-routines*)
+                 (~empty sleeping-routines*))
+             (all [rep._ 'helper] (as cons running-routines*))
              (all [rep._ 'helper] keys.sleeping-routines*))
+    (trace "schedule" "just helpers left; stopping everything")
     (until (empty running-routines*)
       (push (deq running-routines*) completed-routines*))
-    (until sleeping-routines*
-      (push (pop sleeping-routines*) completed-routines*)))
+    (each (routine _) sleeping-routines*
+      (wipe sleeping-routines*.routine)
+      (push routine completed-routines*)))
 ;?   (tr 113)
   (detect-deadlock)
 ;?   (tr 114)
diff --git a/mu.arc.t b/mu.arc.t
index f9c2ef83..2e0e68a8 100644
--- a/mu.arc.t
+++ b/mu.arc.t
@@ -2559,6 +2559,58 @@
   (prn "F - scheduler ignores sleeping but ready threads when detecting deadlock"))
 
 (reset)
+(new-trace "scheduler-helper")
+(= traces* (queue))
+(add-code
+  '((function f1 [
+      (1:integer <- copy 0:literal)
+     ])))
+; just a helper routine
+(= routine* make-routine!f1)
+(set rep.routine*!helper)
+;? (= dump-trace* (obj whitelist '("schedule")))
+(update-scheduler-state)
+(when (or (~empty running-routines*) (~empty sleeping-routines*))
+  (prn "F - scheduler stops when there's only helper routines left"))
+
+(reset)
+(new-trace "scheduler-helper-sleeping")
+(= traces* (queue))
+(add-code
+  '((function f1 [
+      (1:integer <- copy 0:literal)
+     ])))
+; just a helper routine
+(let routine make-routine!f1
+  (set rep.routine!helper)
+  (= rep.routine!sleep '(until-location-changes 23 nil))
+  (set sleeping-routines*.routine))
+;? (= dump-trace* (obj whitelist '("schedule")))
+;? (prn "1 " running-routines*)
+;? (prn sleeping-routines*)
+(update-scheduler-state)
+;? (prn "2 " running-routines*)
+;? (prn sleeping-routines*)
+(when (or (~empty running-routines*) (~empty sleeping-routines*))
+  (prn "F - scheduler stops when there's only sleeping helper routines left"))
+
+(reset)
+(new-trace "scheduler-termination")
+(= traces* (queue))
+(add-code
+  '((function f1 [
+      (1:integer <- copy 0:literal)
+     ])))
+; all routines done
+(update-scheduler-state)
+(check-trace-doesnt-contain "scheduler helper check shouldn't trigger unless necessary"
+  '(("schedule" "just helpers left")))
+
+; both running and sleeping helpers
+; running helper and sleeping non-helper
+; sleeping helper and running non-helper
+
+(reset)
 (new-trace "scheduler-account-slice")
 ; function running an infinite loop
 (add-code