;; nos nut operating system ;; ;; start 12 Jan 2005 ;; run a single thread 21 Jan 2005 ;; run multi thread 24 Jan 2005 ;; signal wait, working 27 Jan 2005 ;; send, receive 20 Feb 2005 ;; nos0 a multi thread, no semaphore ;; update to nut compiler 13 Aug 2006 (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)) ;; --------------------- ;; global var ;; activep the active process ;; status 10 time-out, 11 stopped, 12 blocked ;; pid number of process created (let activep status pid) (let sseg) ;; free stack segment (enum 10 TIMEOUT STOPPED BLOCKED) ;; ---------------------- ;; process descriptor ;; field: ;; 0 next, 1 prev, double link ;; 2 id, 3 value, ;; 4 fp, 5 sp, 6 ip, 7 ts, context ;; 8 inbox, 9 awaitbox, 10 msg mail box ;; ;; process state (value) : ;; 1 READY, 2 RUNNING, 3 WAIT, 4 DEAD, 5 SEND, 6 RECEIVE (enum 1 READY RUNNING WAIT DEAD) (def ei () () (sys 20)) ;; enable int (def di () () (sys 21)) ;; disable int (def blockp () () (sys 22)) ;; block current process ;; 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)) ;; append a2 to the end of a1 (def appendDL (a1 a2) (b) (if (= a1 0) (do (setNext a2 a2) ;; only one item (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 11)) ;; new pdes (setNext p 0) (setPrev p 0) (setValue p READY) (setv p 4 sseg) ;; set fp' (setv p 5 (+ sseg 1)) ;; set sp' (setv p 6 0) ;; set ip' (set sseg (+ sseg 1000)) (setv p 7 0) (setv p 8 0) p)) ;; -------- process management ------- ;; show process list a (def showp (a) (p) (do (set p a) (while (!= p 0) (do (print (vec p 2)) (space) (print (vec p 4)) (space) (print (vec p 7)) (space) (print (vec p 8)) (space) (set p (getNext p)) (if (= p a) (set p 0)))) (nl))) (def wakeup (p) () (do (setValue p READY) (set activep (appendDL activep p)))) ;; return p (def run (ads) (p) (do (set p (newp)) ;; new pdes (setId p pid) (set pid (+ pid 1)) (setv p 6 ads) ;; set ip' to call.fun (set activep (appendDL activep p)) p)) (def runnable (p) () (do (setValue p RUNNING) (sys 24 p))) ;; restore C-state and ei ;; nos sim is responsible to save C-state ;; before running switchp (def switchp2 () (nxt) (do (di) (if (or (= status TIMEOUT) (= status BLOCKED)) (do (set nxt (getNext activep)) (if (= nxt activep) ;; one process (runnable activep) ;; else ;; switch next (do (setValue activep READY) (set activep nxt) (runnable nxt)))) ; else ;; status 11, STOPPED (do (setValue activep DEAD) (set activep (deleteDL activep)) (if (!= activep 0) (runnable activep)))))) ;; nos sim is responsible to save C-state ;; before running switchp (def switchp () () (do (di) (if (or (= status TIMEOUT) (= status BLOCKED)) (do (setValue activep READY) (set activep (getNext activep)) ;; switch next (runnable activep)) ; else ;; status STOPPED (do (setValue activep DEAD) (set activep (deleteDL activep)) (if (!= activep 0) (runnable activep)))))) (def bootnos () () (runnable activep)) ;; ----------- application --------- (def cnt (i n) (k) (do (set k i) (while (< k n) (do (print k) (space) (set k (+ k 10)))))) (def main () (p1 p2 p3) (do (di) (set activep 0) (set sseg 5000) (set pid 1) (set p1 (run (cnt 1 1000))) (set p2 (run (cnt 2 1000))) (set p3 (run (cnt 3 1000))) (bootnos)))