// nos-z nut operating system in Rz // model after nos2 in ecse\src 22 Aug 2011 // for s23 embed sys demo 20 Jan 2013 // s23 trap for nos // 20 enable interrupt // 21 disable interrupt // 22 block // 23 get event // 24 stop simulation asm(x) // dummy for compiler use new(n) // alloc n asm("trap r1 #14") blockp() asm("trap r0 #22") wakeup() asm("trap r0 #25") getEvent() asm("trap r0 #23") ei() asm("trap r0 #20") di() asm("trap r0 #21") // global activep // current active process sseg // stack segment pid // unique process id // process descriptor // 0 next, 1 prev // 2 id, 3 value // 4 fp, 5 sp, 6 pc, // 7 inbox, 8 awaitbox, 9 msg, 10 timer // process state // READY, RUNNING, WAIT, DEAD, SEND, RECEIVE // 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) if(getNext(b) == b) return 0 // delete singleton else a = getPrev(b) c = getNext(b) setNext(a,c) setPrev(c,a) setNext(b,b) // make b singleton return c newp() // new process p = new(11) // new pdes setNext(p,0) setPrev(p,0) p[4] = sseg p[5] = sseg + 500 p[6] = 0 sseg = sseg + 1000 p[7] = 0 p[8] = 0 return p // ----- singly linked circular list -------- // pool of singly circular list numcell, freecell, freelist initH() freecell = new(100) numcell = 100 freelist = 0 newH() if( freelist ) a = freelist freelist = a[1] else a = freecell freecell = freecell + 2 numcell = numcell - 2 if( numcell <= 0 ) print("out of cell") a[0] = 0 a[1] = 0 return a // function prototypes getslist(s) setslist(s,a) freeH(a) a[1] = freelist freelist = a deleteH(s) a = getslist(s) if( a ) b = a[1] info = b[0] if( b == a ) // singleton setslist(s,0) else a[1] = b[1] // delete b freeH(b) else info = 0 return info appendH(s,info) b = newH() b[0] = info a = getslist(s) if( a ) b[1] = a[1] a[1] = b // append b else b[1] = b // singleton setslist(s,b) // -------nos functions -------- init() pid = 1 sseg = 4000 activep = 0 run(ads) // return p p = newp() setId(p,pid) pid = pid + 1 p[6] = ads activep = appendDL(activep, p) return p bootnos() // setup interrupt asm("mov r1 #interrupt") asm("st r1 1000") asm("mov r1 #10") asm("trap r1 #10 ; set timer1 = 10") asm("mov r1 #100") asm("trap r1 #11 ; set div = 100") asm("trap r0 #20 ; enable int") // boot nos // restore fp,sp,pc from activep asm("ld r1 activep") asm("ld fp @4 r1") asm("ld sp @5 r1") asm("ld r2 @6 r1") asm("ret r2") interrupt() // switchp() asm("trap r0 #21") // di asm("ld r21 activep") // save activep asm("st fp @4 r21") asm("st sp @5 r21") asm("st r31 @6 r21") print("*") // print(" * save",activep) event = getEvent() if(event == 11 || event == 13)// 11 TIMEOUT, 13 WAKEUP activep = getNext(activep) // switch next else // 10 STOP, 12 BLOCK activep = deleteDL(activep) if(activep == 0) asm("trap r0 #24") // stop simulation // print(" res",activep) // restore activep asm("ld r21 activep") asm("ld fp @4 r21") asm("ld sp @5 r21") asm("ld r31 @6 r21") asm("trap r0 #20") // 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() s = new(2) setsval(s,1) setslist(s,0) // wait-list null return s signal(s) di() v = getsval(s)+1 setsval(s,v) // print("%",s,v) if(v <= 0) p = deleteH(s) activep = appendDL(activep,p) wakeup() ei() wait(s) di() v = getsval(s)-1 setsval(s,v) // print("@",s,v) if( v < 0 ) // block activep appendH(s,activep) blockp() ei() // --- use semaphore to protect share resource ------ empty, full, mutex // semaphores shareVar writer() i = 0 while( i < 3 ) wait(empty) wait(mutex) shareVar = shareVar + 1 signal(mutex) signal(full) i = i + 1 reader() i = 0 while( i < 3 ) wait(full) wait(mutex) print("+",shareVar) signal(mutex) signal(empty) i = i + 1 // ------------------------------ p1, p2 // user process main() initH() init() shareVar = 0 empty = initsem() full = initsem() mutex = initsem() p1 = run(writer()) p2 = run(reader()) bootnos() // end