.Title AdjustPri ; ; Routine to adjust priority of running interactive processes. ; ; When such a process exceeds an execution time threshold for ; its current base priority, the base priority is lowered. ; ; Execution of a new image restores the original priority. ; ; The intent of this task is to improve response time ; for interactive jobs without forcing long computations to batch. ; ; All site-dependent parameters such of frequency of execution ; of the task, time thresholds, maximum number of processes, ; and group numbers to exclude from consideration are defined at ; the beginning of the program. ; ; Coded 11-May-1982 ; ; Larry W. Finger ; Geophysical Laboratory ; 2801 Upton St. N.W. ; Washington DC 20008 ; (202) 966-0334 ; ; ; Define symbols to set-up program ; NoProc = ^D100 ; Size of Process Tables, Maximum No. LowGrpNum = ^O100 ; Lowest Group Number to consider LoopTime = ^D15 ; Number of seconds Between Rescans Time1 = ^D5 ; Execution Time before Dropping 1 Priority Level Time2 = ^D300 ; Cpu Time before Dropping Second Level Time3 = ^D1800 ; Cpu Time before Dropping Third Level Time4 = ^D1800 ; Cpu Time before dropping Fourth Level Time5 = ^D1800 ; Cpu Time before Dropping Fifth Level Time6 = ^D1800 ; Cpu Time before Dropping Sixth Level Time7 = ^D1800 ; Cpu Time before Dropping Seventh Level ; $jpidef ;define $GETJPI item codes .page ; ; read/only data ; .psect rodata,rd,nowrt,noexe ; ; Item List for $GETJPI ; items: .word 16 ;process name buffer .word JPI$_PRCNAM ;process name code .long pcname ;pointer to buffer .long 0 ;length not needed .word 4 ;length of cputime buffer .word JPI$_CPUTIM ;cpu time code .long cputime .long 0 ;length not needed .word 4 .word JPI$_PRIB ;base priority code .long basepri .long 0 ;length not needed .word 4 .word JPI$_GRP ;group number code .long grpnum .long 0 ;length not needed .word 64 .word JPI$_IMAGNAME ;image name code .long imgnam .long 0 ;length not needed .word 4 .word JPI$_PID ;user pid code .long userpid .long 0 ;length not needed .long 0 ;end of list ; DayTime:.long -^D10*^D1000*^D1000*LoopTime,-1 ;Delta Time for Rescans ; Times: .long ^D100*Time1 ; Table of Cpu Time Differences .long ^D100*Time2 ; for Priority Change .long ^D100*Time3 .long ^D100*Time4 .long ^D100*Time5 .long ^D100*Time6 .long ^D100*Time7 .page ; ; read/write data ; .psect rwdata,rd,wrt,noexe pid: .long -1 ;"wildcard" PID ; pcname: .blkb 16 ;process name buffer cputime:.blkl 1 ;cputime storage basepri:.blkl 1 ;current base priority grpnum: .blkl 1 ;group number imgnam: .blkb 64 ;image name buffer userpid:.blkl 1 ; iosb: .blkq 1 ;i/o status block ; ; Process Storage Tables ; PidTab: .blkl NoProc ; Storage Array for PID's Imgnamtab:.blkq NoProc ; Storage for Current Image OrigBas:.blkl NoProc ; Original Base Priority OrigCpu:.blkl NoProc ; Cpu time at start of execution of this image Prcusd: .blkb NoProc ; Byte to keep track whether this slot used ; Frstmty:.blkl 1 ; Word Containing Location of First Empty Slot PidCnt: .blkl 1 ; Number of Entries in PID Tables .page ; ; executable section ; .psect code,exe,nowrt ; .entry start,^m<> ; clrl pidcnt ;make pid table empty restart: ;restart loop after initial pass ; ; clear process used storage area ; movl #-1,r4 ;initialize a counter movl r4,pid ;restore wildcard PID 10$: incl r4 ;increment counter cmpl r4,pidcnt ;at end of list? beql loop ;if eql yes clrb prcusd[r4] ;set slot not used this loop brb 10$ ;go to next entry ; ; loop through all processes in system ; loop: $GETJPI_S efn=#1,pidadr=pid,itmlst=items,iosb=iosb ;get info. blbs r0,wait ;if success, continue cmpw r0,#SS$_NOMOREPROC ;end of list? bneq loop ;if neq no brw done ;go to done wait: $WAITFR_S efn=#1 ;wait for info ready cmpl grpnum,#lowgrpnum ;should this group be ignored? blss loop ;if lss yes cmpb pcname,#^O137 ;BATCH job - Underscore as first character? beql loop ;if eql yes - ignore ; ; find process in tables ; movl #-1,r4 ;preset loop counter movl r4,frstmty ;invalidate first empty slot marker 20$: incl r4 ;update counter cmpl r4,pidcnt ;at end of list? beql 40$ ;if eql yes tstl pidtab[r4] ;slot empty? bneq 30$ ;if neq no tstl frstmty ;is this first empty this scan? bgeq 20$ ;if geq no movl r4,frstmty ;save this empty slot as first brb 20$ ;go to check next slot 30$: cmpl pidtab[r4],userpid ;slot not empty - match current PID? bneq 20$ ;if neq no brb 70$ ;found match - go to process ; ; new process found - not in current tables ; 40$: tstl frstmty ;imbedded empty slot? bgeq 50$ ;if geq yes movl pidcnt,r4 ;add new process at end - get current count incl r4 ;update by one cmpl r4,#noproc ;exceed size of tables? bgtr 45$ ;if gtr yes - ignore process movl r4,pidcnt ;update count decl r4 ;restore pointer brb 60$ 45$: brw loop ;get next process 50$: movl frstmty,r4 ;fill in empty slot - get its number ; ; add new process info to tables ; 60$: movl userpid,pidtab[r4] ;store PID in table movl cputime,origcpu[r4] ;cpu time movl basepri,origbas[r4] ;starting priority bsbw scanname ;get pointer to start of image file name movq (r0),imgnamtab[r4] ;copy first 8 characters of image name ; ; process in tables (just added if necessary) - compare with previous entry ; 70$: incb prcusd[r4] ;mark this entry used bsbw scanname ;scan image name for closing ] movl r0,r6 ;save r0 movaq imgnamtab[r4],r5 ;get index to old name cmpc3 #^D8,(r5),(r0) ;same image? bneq 80$ ;if neq no ; ; still executing previous image ; subl3 origcpu[r4],cputime,r0 ;compute ticks used subl3 basepri,origbas[r4],r1 ;get difference in priority cmpl r0,times[r1] ;time exceed threshold? bleq 90$ ;if leq no ; ; time over threshold ; subl3 #1,basepri,r0 ;reduce base priority by 1 - to zero? bleq 90$ ;if leq yes - ignore setting new priority bsbw setpriority ;set new priority for this process brb 90$ ; ; new image executing ; 80$: movl cputime,origcpu[r4] ;reset cpu start movq (r6),imgnamtab[r4] ;copy first 8 characters of image name movl origbas[r4],r0 ;get original base priority cmpl r0,basepri ;any change? beql 90$ ;if eql no bsbw setpriority ;reset priority 90$: brw loop ;get next entry ; ; end of process loop ; done: ; ; leave wake-up call for 'LOOPTIME' seconds from now ; $SCHDWK_S daytim=daytime ; ; clear PID entry for anyone that logged off ; clrl r4 ;zero index register 10$: tstb prcusd[r4] ;this process still around? bneq 20$ ;if neq yes clrl pidtab[r4] ;process gone - zero pid entry 20$: incl r4 ;update counter cmpl r4,pidcnt ;at end yet? blss 10$ ;if lss no ; ; prune last entry from list if not used ; movl pidcnt,r4 ;get pidcnt - tables empty? beql 30$ ;if eql yes decl r4 ;reduce number by 1 tstl pidtab[r4] ;last entry empty? bneq 30$ ;if neq no movl r4,pidcnt ;prune empty entry from end of list 30$: $HIBER_S ;go to sleep brw restart ;do it again ; ; scanname - routine to scan for closing ] in imagename ; ; address of start of program name returned in r0 ; scanname: moval imgnam,r0 ;pointer to start of image area movl #^D40,r1 ;maximum number of characters before ] 10$: cmpb (r0)+,#^O135 ;character = ]? beql 20$ ;if eql yes sobgtr r1,10$ ;loop for next character moval imgnam,r0 ;if loop exited - no ] in name 20$: rsb ;exit with r0 set ; ; setpriority - routine to adjust priority of process ; ; new base priority in r0 at entry ; process identification in 'userpid' ; setpriority: $SETPRI_S pidadr=userpid,pri=r0 ;set new priority rsb ;exit .end start