;; nos nut operating system ;; ;; start 12 Jan 2005 ;; run a single thread 21 Jan 2005 (def print (x) () (sys 1 x)) (def printc (c) () (sys 2 c)) (def nl () () (sys 2 10)) (def space () () (sys 2 32)) (def not (b) () (if b 0 1)) (def != (a b) () (if (= a b) 0 1)) (def <= (a b) () (if (> a b) 0 1)) (def >= (a b) () (if (< a b) 0 1)) (def or (a b) () (if a 1 b)) (def and (a b) () (if a b 0)) ;; --------------------- ;; global var (let activep status) (let sseg) ;; stack segment (let sa sb) ;; semaphore ;; ---------------------- ;; process descriptor ;; next prev id value {ip,fp,sp} inbox awaitbox ;; process state (value) : 1 READY, 2 RUNNING, 3 WAIT, 4 DEAD ;; semaphore ;; value wait-list ;; doubly linked list (def getNext (a) () (vec a 0)) (def getPrev (a) () (vec a 1)) (def setNext (a v) () (setv a 0 v)) (def setPrev (a v) () (setv a 1 v)) ;; insert a2 into a1 (def insertDL (a1 a2) (b) (if (= a1 0) (do (setNext a2 a2) ;; only one process (setPrev a2 a2) a2) ;; else (do (set b (getPrev a1)) (setNext a2 a1) (setPrev a1 a2) (setNext b a2) (setPrev a2 b) a1))) (def deleteDL (b) (a c) (if (= b (getNext b)) 0 ;; delete singleton ;; else (do (set a (getPrev b)) (set c (getNext b)) (setNext a c) (setPrev c a) c))) ;; process descriptor access functions (def getId (p) () (vec p 2)) (def getValue (p) () (vec p 3)) (def setId (p id) () (setv p 2 id)) (def setValue (p v) () (setv p 3 v)) (def newp () (p) (do (set p (new 9)) ;; new pd (setNext p 0) (setPrev p 0) (setValue p 1) ;; READY (setv p 4 sseg) ;; set fp' (setv p 5 (+ sseg 1)) ;; set sp' (setv p 6 0) ;; set ip' (set sseg (+ sseg 1000)) p)) ;; semaphore access functions (def getsval (s) () (vec s 0)) (def getslist (s) () (vec s 1)) (def setsval (s v) () (setv s 0 v)) (def setslist (s v) () (setv s 1 v)) ;; ---------------------- (def showp () (p) (do (set p activep) (while (!= p 0) (do (print (getId p)) (space) (set p (getNext p)) (if (= p activep) (set p 0)))) (nl))) (def wakeup (p) () (do (setValue p 1) ;; READY (set activep (insertDL activep p)))) (def signal (s) (p nxt) (do (sys 5) ;; disable interrupt (set p (getslist s)) (if (!= p 0) (do (set nxt (getNext p)) (setNext p (deleteDL p)) (setslist s nxt) (wakeup p)) ;; else (setsval s (+ (getsval s) 1))) (sys 6))) ;; enable interrupt (def wait (s) (v p) (do (sys 5) ;; DI (set v (getsval s)) (if (<= v 0) (do ;; block activep to WAIT (set p activep) (set activep (deleteDL activep)) (setValue p 3) ;; WAIT (setslist s (insertDL (getslist s) p))) ;; to wait-list ;; else (setsval s (- v 1))) (sys 6))) ;; EI ;;(def saveCstate (p) () ;; (sys 8 p)) ;; (do ;; (setv p 4 fp) ;; (setv p 5 sp) ;; (setv p 6 ip))) ;;(def restoreCstate (p) () ;; (sys 9 p)) ;; (do ;; (set fp (vec p 4)) ;; (set sp (vec p 5)) ;; (set ip (vec p 6)))) (def run (ads) (p) (do (sys 5) (set p (newp)) ;; new pd (setv p 6 ads) ;; set ip' to call.fun (set activep (insertDL activep p)) ;; at tail (sys 6))) (def runnable (p) () (do (setValue p 2) ;; RUNNING (sys 9 p))) ;; restore C-state and ei ;; nos sim is responsible to save C-state ;; before running switchp (def switchp () (nxt) (do (sys 5) ;; disable interrupt (if (or (= status 10) (= status 12)) (do ;; time-out/blocked (set nxt (getNext activep)) (if (= nxt activep) ;; one process (runnable activep) ;; else ;; switch next (do ;; (sys 8 activep) ;; save current C-state (setValue activep 1) ;; READY (set activep nxt) (runnable nxt)))) ;; else ;; status 11, stopped (do (set activep (deleteDL activep)) (if (= activep 0) (set status 13) ;; empty ;; else (runnable activep)))) (sys 6))) ;; enable int (def bootnos () () (runnable activep)) ;; ---- application -------- (def count (n) (i) (do (set i 0) (while (< i n) (do (set i (+ i 1)) (print i) (space))))) (def main () (p) (do (sys 5) ;; di (set activep 0) (set sseg 1000) (run (count 500)) (bootnos)))