$MACRO REGS $ENDM / program .mcall read$,write$,wait$ ; trace=50. ;if defined, trace results nofile=-26. nl=12 eof=-10. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct bfdb ;buffered fdb's bfdb=-32. member b.lh,b.lhl[4],b.max[1],b.cur[1] member b.type,b.dirty,b.stat,b.seek[4] member b.stype,b.ssize,b.sracc member b.io,b.prec,b.pos,b.check end-struct ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - struct l.lru ;Lru lists member l.blk[4],l.dirty,l.data[512.] end-struct ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .title lru ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .if df trace .blkw 10 statg:: .blkw trace statp:: .blkw trace statr:: .blkw trace statw:: .blkw trace .endc ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - auto ind function getblk[fdb] ; gets the blk seek describes r4 := fdb .if df trace seekbk[r4] ind := r1 ; fprintf[stdout,"get block=%d__",ind] if ind ge 0 and ind lt #trace .statg[ind] := .statg[ind] + 1 fi .endc r3 := lruget[r4] ;get an lru rec with our block b.dirty(r4) := l.dirty(r3) ;use its dirty indicator b.prec(r4) := r3 + #l.data ;set up buffer pointer insert[b.lh(r4),r3] ;put at head of list movb f.err(r4),r0 ret ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern statg,statp auto p,i function lrufin[fdb] r4 := #b.lh[fdb] r3 := next[r4] if r3 ne r4 l.dirty(r3) := #b.dirty[fdb] fi i := 0 do forever r3 := next[r4] break if r3 = r4 wtblk[fdb,r3] if i ne 0 ;don't del cur, just write release[delete[r3]] fi inc i od .if df trace loop for r4 := 0 to #trace-1 fprintf[stdout, "rd(%d)=%d wt=%d__" .statr[r4] .statw[r4]] next r4 loop for r4 := 1 to #trace-1 fprintf[stdout, "g(%d)=%d p=%d__" r4 .statg[r4] .statp[r4]] next r4 .endc ret ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - auto lp,p function lrufnd[fdb] r4 := fdb lp := b.lh(r4) p := lp seekbk[r4] mov r0,r3 mov r1,r4 do forever r0 := next[p] p := r0 break if r0 = lp if r4 = l.blk(r0) if r3 = l.blk+2(r0) ret fi fi od clr r0 ret ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function lruget[fdb] ;fdb seek used as key, get an lru rec r4 := fdb ;pre-empt or get new block if necessary r3 := lrufnd[fdb] if r3 ne 0 delete[r3] ret r3 fi ifb b.cur(r4) lt b.max(r4) r3 := new[#l.lru] incb b.cur(r4) else r3 := prev[b.lh(r4)] wtblk[r4,r3] delete[r3] fi setblk[r4,r3] rdblk[r4,r3] ret r3 ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function lrumax[fd,max] r4 := fd movb max(r5),b.max(r4) ret ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function lruset[fdb] r4 := fdb ilist[] clrb b.cur(r4) ret ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - auto ind function putblk[fdb] ;simply marks the block as dirty r4 := fdb .if df trace r3 := next[b.lh(r4)] ;find the block (first in list) ind := l.blk(r3) ; fprintf[stdout,"put block=%d__",ind] if ind ge 0 and ind lt #trace .statp[ind] := .statp[ind] + 1 fi .endc r3 := next[b.lh(r4)] ;find the block (first in list) l.dirty(r3) := 0 ;clear = dirty movb f.err(r4),r0 ;return any prev error status ret ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern statg,statp auto ind function rdblk[fdb,lrurec] r4 := fdb .if df trace ind := #l.blk[lrurec] - 1 ; fprintf[stdout,"rd block=%d__",] if ind ge 0 and ind lt #trace .statr[ind] := .statr[ind] + 1 fi .endc r3 := lrurec mov l.blk(r3),f.bkvb+2(r4) mov l.blk+2(r3),f.bkvb(r4) r3 := r3 + #l.data mov r4,r0 read$ r0,r3,#512. if cc wait$ fi r3 := r3 - #l.data l.dirty(r3) := 1 ; f.err(r4) := 1 ret f.err(r4) ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function seekbk[fdb] ;return in r0/r1 the block number r4 := fdb ;from the fdb seek r0 := b.seek+2(r4) r1 := b.seek(r4) ashc #-9.,r0 add #1,r1 adc r0 ret ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - function setblk[fdb,lrurec] ; set block number into lru rec r3 := lrurec ;from fdb seek seekbk[fdb] mov r0,l.blk+2(r3) mov r1,l.blk(r3) ret ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .if df trace .blkw 10 statg:: .blkw trace statp:: .blkw trace statr:: .blkw trace statw:: .blkw trace .endc ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - extern statg,statp auto ind function wtblk[fdb,lrurec] r4 := fdb .if df trace ind := #l.blk[lrurec] - 1 ; fprintf[stdout,"wt block=%d__",] if ind ge 0 and ind lt #trace .statw[ind] := .statw[ind] + 1 fi .endc r3 := lrurec if l.dirty(r3) = 0 mov l.blk(r3),f.bkvb+2(r4) mov l.blk+2(r3),f.bkvb(r4) r3 := r3 + #l.data mov r4,r0 write$ r0,r3,#512. if cc wait$ fi fi movb f.err(r4),r0 ret .end