diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2014-11-06 15:38:00 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2014-11-06 16:05:57 -0800 |
commit | 64579cf7c812e4ffe659fc6f1b1614bfc5848f22 (patch) | |
tree | e695c9b2855d863ebf5da681b3e28a15842f6977 | |
parent | f462b986b1b2d2dae4f8b6a7416fb1b995a00d85 (diff) | |
download | mu-64579cf7c812e4ffe659fc6f1b1614bfc5848f22.tar.gz |
237 - rudimentary 'sleep'
-rw-r--r-- | mu.arc | 26 | ||||
-rw-r--r-- | mu.arc.t | 24 |
2 files changed, 47 insertions, 3 deletions
diff --git a/mu.arc b/mu.arc index 4395bc27..5779ac47 100644 --- a/mu.arc +++ b/mu.arc @@ -171,6 +171,8 @@ (on-init (= running-routines* (queue)) (= completed-routines* (queue)) + ; set of sleeping routines; don't modify routines while they're in this table + (= sleeping-routines* (table)) (= routine* nil) (= abort-routine* (parameter nil)) (= curr-cycle* 0) @@ -189,12 +191,23 @@ (enq make-routine.it running-routines*)) ; simple round-robin scheduler (while (~empty running-routines*) + (each (routine _) sleeping-routines* + (awhen (> curr-cycle* rep.routine!sleep.1) + (trace "schedule" "waking up " top.routine!fn-name) + (wipe sleeping-routines*.routine) ; before modifying routine below + (wipe rep.routine!sleep) + (++ pc.routine) ; complete the sleep instruction + (enq routine running-routines*))) (= routine* deq.running-routines*) (trace "schedule" top.routine*!fn-name) (routine-mark:run-for-time-slice scheduling-interval*) - (if (~empty routine*) - (enq routine* running-routines*) - (enq-limit routine* completed-routines*)))) + (if rep.routine*!sleep + (do (trace "schedule" "pushing " top.routine*!fn-name " to sleep queue") + (set sleeping-routines*.routine*)) + (~empty routine*) + (enq routine* running-routines*) + :else + (enq-limit routine* completed-routines*)))) (def die (msg) (= rep.routine*!error msg) @@ -202,6 +215,11 @@ (wipe rep.routine*!call-stack) ((abort-routine*))) +(def sleep-for (delay) + (trace "run" "sleeping until " (+ curr-cycle* delay)) + (= rep.routine*!sleep `(literal ,(+ curr-cycle* delay))) + ((abort-routine*))) + ;; running a single routine (mac v (operand) ; for value `(,operand 0)) @@ -465,6 +483,8 @@ ; inspect it assert (assert (m arg.0)) + sleep + (sleep-for (m arg.0)) ; text interaction cls diff --git a/mu.arc.t b/mu.arc.t index e8257606..41561520 100644 --- a/mu.arc.t +++ b/mu.arc.t @@ -1674,6 +1674,30 @@ ("run" "f2 1") )) +(reset) +(new-trace "sleep") +(add-fns + '((f1 + (sleep (1 literal)) + ((1 integer) <- copy (3 literal)) + ((1 integer) <- copy (3 literal))) + (f2 + ((2 integer) <- copy (4 literal)) + ((2 integer) <- copy (4 literal))))) +;? (= dump-trace* (obj whitelist '("run" "schedule"))) +(= scheduling-interval* 1) +(run 'f1 'f2) +(check-trace-contents "scheduler handles sleeping routines" + '(("run" "f1 0") + ("run" "sleeping until 2") + ("schedule" "pushing f1 to sleep queue") + ("run" "f2 0") + ("run" "f2 1") + ("schedule" "waking up f1") + ("run" "f1 1") + ("run" "f1 2") + )) + ; The scheduler needs to keep track of the call stack for each routine. ; Eventually we'll want to save this information in mu's address space itself, ; along with the types array, the magic buffers for args and oargs, and so on. |