// nos-z nut operating system in Rz // model after nos2 in ecse\src 22 Aug 2011 // run two process (showTwoCount) 23 Aug 2011 // new Rz syntax 28 Aug 2011 // add message passing 31 Aug 2011 syscall() // anchor for compiler a = 0 new(n) // alloc n syscall(14,n) ei() syscall(20) di() syscall(21) getevent() syscall(22) blockp() syscall(23) bootnos() syscall(24) // global activep // current active process psw // switchp sseg // stack segment pid // unique process id // event TIMEOUT, STOP, BLOCK // process descriptor // 0 next, 1 prev // 2 id, 3 value // 4 fp, 5 sp, 6 pc, 7 - // 8 inbox, 9 awaitbox, 10 msg // process state READY, RUNNING, WAIT, DEAD, SEND, RECEIVE init() TIMEOUT = 10 STOP = 13 BLOCK = 11 READY = 1 RUNNING = 2 WAIT = 3 DEAD = 4 SEND = 5 RECEIVE = 6 pid = 1 sseg = 1000 activep = 0 // process descriptor access function getNext(a) return a[0] getPrev(a) return a[1] setNext(a,v) a[0] = v setPrev(a,v) a[1] = v getId(p) return p[2] getValue(p) return p[3] setId(p,id) p[2] = id setValue(p, v) p[3] = v // ---- process list functions -------- // append a2 to the end of a1 appendDL(a1,a2) if(a1 == 0) setNext(a2,a2) // only one item setPrev(a2,a2) return a2 else b = getPrev(a1) setNext(a2,a1) setPrev(a1,a2) setNext(b,a2) setPrev(a2,b) return a1 deleteDL(b) c = getNext(b) if(c == 0 || c == b) return 0 // delete singleton else a = getPrev(b) setNext(a,c) setPrev(c,a) setNext(b,0) // make b singleton return c showp(a) // show pid,sseg,ip p = a while(p != 0) print(p[2]," ",p[4]," ",p[6],"\n") p = getNext(p) if(p == a) p = 0 print("\n") newp() // new process p = new(11) // new pdes setNext(p,0) setPrev(p,0) setValue(p,READY) p[4] = sseg p[5] = sseg + 1 p[6] = 0 sseg = sseg + 1000 p[7] = 0 p[8] = 0 return p // -------nos functions -------- run(ads) // return p p = newp() setId(p,pid) pid = pid + 1 p[6] = ads activep = appendDL(activep, p) return p switchp() // previlege process di() event = getevent() if(event == STOP) setValue(activep,DEAD) activep = deleteDL(activep) else setValue(activep,READY) activep = getNext(activep) // switch next ei() // ------- semaphore ------ // field: svalue(value) slist(wait-list) // semaphore access functions getsval(s) return s[0] getslist(s) return s[1] setsval(s,v) s[0] = v setslist(s,v) s[1] = v initsem(v) s = new(2) setsval(s,v) setslist(s,0) // wait-list null return s wakeup(p) setValue(p,READY) activep = appendDL(activep,p) signal(s) di() p = getslist(s) if(p != 0) setslist(s,deleteDL(p)) wakeup(p) else setsval(s,getsval(s)+1) ei() wait(s) di() v = getsval(s) if( v <= 0 ) // block activep p = activep activep = deleteDL(activep) setValue(p,WAIT) // to wait-list setslist(s,appendDL(getslist(s),p)) blockp() else setsval(s,v-1) ei() // --------- message passing -------- getMbox(p) return p[8] getAwait(p) return p[9] getMsg(p) return p[10] setMbox(p,m) p[8] = m setAwait(p,m) p[9] = m setMsg(p,m) p[10] = m // search mail p in the box // return mail if found else 0 findmail(p,box) y = 0 // return value x = box while( x != 0 ) if( x == p ) y = x x = 0 // exit else x = getNext(x) if( x == box ) x = 0 // not found return y // p is pointer to process send(p,mess) di() box = getAwait(activep) m = findmail(p,box) if( m == 0 ) m = activep // self setMsg(m,mess) activep = deleteDL(activep) setMbox(p,appendDL(getMbox(p),m)) setValue(m,SEND) blockp() else // p is waiting setMsg(p,mess) m = deleteDL(p) if( box == p ) setAwait(activep,m) wakeup(p) ei() receive(p) di() box = getMbox(activep) m = findmail(p,box) if( m == 0 ) // put to await p m = activep // self activep = deleteDL(activep) setAwait(p,appendDL(getAwait(p),m)) setValue(m,RECEIVE) blockp() getMsg(m) // retrieve from self else // already in mbox m = deleteDL(p) if( box == p ) setMbox(activep,m) getMsg(p) // retrieve mbox wakeup(p) ei() // -------- user program ------ p1, p2 // user process count1() i = 10 while(i < 100) print(i," ") i = i + 2 count2() i = 3 while(i < 100) print(i," ") i = i + 2 showTwoCount() p1 = run(count1()) p2 = run(count2()) // ----- process synchronisation using two semaphores semx, semy // semaphore prox() i = 0 while( i < 10 ) wait(semy) signal(semx) print(" x:",i) i = i + 1 proy() i = 0 while( i < 10 ) wait(semx) signal(semy) print(" y:",i) i = i + 1 showSync() semx = initsem(0) semy = initsem(1) p1 = run(prox()) p2 = run(proy()) // --- producer, consumer ---- // send 2..n to p2 ended with -1 produce() n = 10 i = 2 while( i < n ) send(p2,i) i = i + 1 send(p2,-1) // receive 2..n from p1 ended with -1 consume() m = 1 while( m > 0 ) m = receive(p1) print(m," ") showProduce() p1 = run(produce()) p2 = run(consume()) // ------ sum array ------- ax, sem1, sem2 initax() ax = new(50) i = 0 while( i < 20 ) ax[i] = i i = i + 1 // print(ax[19]) sumodd() i = 1 sum = 0 while( i < 20 ) sum = sum + ax[i] i = i + 2 ax[1] = sum wait(sem1) signal(sem2) print("sum ", ax[0] + ax[1]) sumeven() i = 0 sum = 0 while( i < 20 ) sum = sum + ax[i] i = i + 2 ax[0] = sum wait(sem2) signal(sem1) // print("sum even ", ax[0]) showSum() sem1 = initsem(0) sem2 = initsem(1) p1 = run(sumodd()) p2 = run(sumeven()) // ----------------- main() init() psw = run(switchp()) activep = 0 // start user process // showTwoCount() // showSync() // showProduce() initax() showSum() bootnos() // end