windows-nt/Source/XPSP1/NT/base/mvdm/wow16/kernel31/2glru.asm
2020-09-26 16:20:57 +08:00

596 lines
12 KiB
NASM

TITLE GLRU - Primitives for LRU management
.xlist
include kernel.inc
include newexe.inc
include tdb.inc
include protect.inc
.list
DataBegin
;externB EMSSwapDepth
externB Kernel_InDOS
externB Kernel_flags
;externW curTDB
externW loadTDB
externW pGlobalHeap
;externW hExeSweep
DataEnd
sBegin CODE
assumes CS,CODE
externW gdtdsc
externNP GetAccessWord
externNP DPMIProc
;-----------------------------------------------------------------------;
; lrusweep ;
; ;
; Searches all of the exe headers in the system for segments that have ;
; been accessed since the last time through. For each segment found ;
; its referenced byte is reset and that segment is moved to the top ;
; of the lru chain. This routine is called (default) every 4 timer ;
; ticks from the int 8 handler. ;
; ;
; Arguments: ;
; none ;
; ;
; Returns: ;
; nothing ;
; ;
; Error Returns: ;
; ;
; Registers Preserved: ;
; DX,DI,SI,DS ;
; ;
; Registers Destroyed: ;
; AX,BX,CX,ES ;
; ;
; Calls: ;
; glrutop ;
; ;
; History: ;
; ;
; Tue Apr 21, 1987 06:22:41p -by- David N. Weise [davidw] ;
; Added the check for discarded segments. ;
; ;
; Wed Apr 08, 1987 11:00:59a -by- David N. Weise [davidw] ;
; Made it clear only the curTask's private handle table. ;
; ;
; Wed Feb 18, 1987 08:13:35p -by- David N. Weise [davidw] ;
; Added the sweeping of the private handle tables. ;
; ;
; Tue Feb 10, 1987 02:11:40a -by- David N. Weise [davidw] ;
; Added this nifty comment block. ;
;-----------------------------------------------------------------------;
cProc lrusweep,<PUBLIC,FAR>
cBegin nogen
push dx
push di
push si
push ds
xor di,di
SetKernelDS
cmp kernel_InDOS,0 ; SMARTDrive and EMS may be present
jnz dont_do_it ; => disk buffers over the code segs
cmp di,loadTDB ; Ignore interrupt if loading task
jnz dont_do_it
mov ds,pGlobalHeap
UnSetKernelDS
cmp di,ds:[di].gi_lrulock ; Ignore interrupt if inside memory
jz do_it ; manager
dont_do_it:
jmps sweepdone
do_it:
mov cx, ds:[di].gi_lrucount
jcxz stuff_it
mov si, ds:[di].gi_lruchain
push bx
push ds
;; For WOW dpmi will update the ACCESSED bits from the real LDT in NT on timer ticks
;; So it will not be totally accurate but will be accurate enough. mattfe apr16 92
mov ds, gdtdsc ; Go grab it out of the LDT
sweep_loop:
mov es, si
mov si, es:[di].ga_lrunext
mov bx, es:[di].ga_handle
sel_check bl
if KDEBUG
test ds:[bx].dsc_hlimit, DSC_DISCARDABLE
jnz sweep_ok
INT3_WARN
sweep_ok:
endif
test ds:[bx].dsc_access, DSC_ACCESSED ; Segment accessed?
jz sweep_next
ifdef WOW
push cx
xor cx,cx
mov cl, ds:[bx].dsc_access
and cx, not DSC_ACCESSED
DPMICALL 0009h
pop cx
jnc @f
INT3_WARN
@@:
else
and ds:[bx].dsc_access, not DSC_ACCESSED
endif ; WOW
pop ds
call glrutop
push ds
mov ds, gdtdsc
sweep_next:
loop sweep_loop
pop ds
pop bx
stuff_it:
sweepdone:
pop ds
pop si
pop di
pop dx
ret
cEnd nogen
;
; Entry:
; DI == 0
; DS:SI.gi_lruchain -> head of list
; ES:0 -> arena header of object to insert
; DX = 0 => insert at head of list
; !=0 => insert at tail of list
;
; Exit:
; BX,DX destroyed
;
cProc LRUInsert,<PUBLIC,NEAR>
cBegin nogen
inc ds:[si].gi_lrucount ; Increment count of LRU entries
mov bx,ds:[si].gi_lruchain ; BX = head of list
or dx,dx ; Inserting at head of chain?
jnz lruins0 ; No, tail so dont update head
mov ds:[si].gi_lruchain,es ; Yes, make new one the new head
lruins0:
or bx,bx ; List empty?
jnz lruins1
mov es:[di].ga_lruprev,es ; Yes, make circular
mov es:[di].ga_lrunext,es
mov ds:[si].gi_lruchain,es
ret
lruins1:
push es ; Save ES
push bx ; ES = insertion point
mov bx,es ; BX = new
mov dx,es ; DX = new
pop es
xchg es:[di].ga_lruprev,bx
mov es,bx
xchg es:[di].ga_lrunext,dx
pop es
mov es:[di].ga_lruprev,bx
mov es:[di].ga_lrunext,dx
ret
cEnd nogen
;
; Entry:
; DI == 0
; DS:SI.gi_lruchain -> head of list
; ES:0 -> arena header of object to insert
;
; Exit:
; BX,DX destroyed
;
;
cProc LRUDelete,<PUBLIC,NEAR>
cBegin nogen
;
; This is basically a consistency check, in case we don't fix
; GlobalRealloc() for 3.1.
;
push ax
mov ax,es:[di].ga_lrunext
or ax,es:[di].ga_lruprev
pop ax
jz lrudel_ret
dec ds:[si].gi_lrucount ; Decrement count of LRU entries
jnz lrudel0
mov ds:[si].gi_lruchain,di ; List empty, zero LRU chain.
mov es:[di].ga_lruprev,di ; Zero pointers in deleted object
mov es:[di].ga_lrunext,di
ret
lrudel0:
mov dx,es
cmp ds:[si].gi_lruchain,dx ; Are we deleting the head?
jne lrudel1
mov dx,es:[di].ga_lrunext
mov ds:[si].gi_lruchain,dx ; Yes, make it point to the next one
lrudel1:
xor bx,bx ; Zero pointers in deleted object
xchg es:[di].ga_lrunext,bx
xor dx,dx
xchg es:[di].ga_lruprev,dx
push es
mov es,dx
mov es:[di].ga_lrunext,bx
mov es,bx
mov es:[di].ga_lruprev,dx
pop es
lrudel_ret:
ret
cEnd nogen
;
; glruSetup
;
; INPUT: ES -> arena header
; DI = 0
;
; OUTPUT: ZF set: block is not on LRU list
; ZF clear:
; SI = 0
;
;
cProc glruSetup,<PUBLIC,NEAR>
cBegin nogen
mov bx,es:[di].ga_handle
or bx,bx
jz gsdone
push ax
cCall GetAccessWord,<bx>
test ah, DSC_DISCARDABLE
pop ax
jz gsdone ; not a discardable object
xor si,si
or sp,sp
gsdone:
ret
cEnd nogen
;-----------------------------------------------------------------------;
; glrutop ;
; ;
; Moves a discardable object to the head of the LRU chain. ;
; ;
; Arguments: ;
; DS:DI = address of global heap info ;
; ES:DI = global arena of moveable object ;
; ;
; Returns: ;
; Updated LRU chain ;
; ;
; Error Returns: ;
; ;
; Registers Preserved: ;
; CX,DX,SI,DS,ES ;
; ;
; Registers Destroyed: ;
; ;
; Calls: ;
; ;
; History: ;
; ;
; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
; Added support for EMS. ;
; ;
; Mon Oct 27, 1986 04:20:10p -by- David N. Weise [davidw] ;
; Rewrote it to eliminate the handle table as intermediary. ;
;-----------------------------------------------------------------------;
cProc glrutop,<PUBLIC,NEAR>
cBegin nogen
push bx
push dx
push si
call glruSetup
jz glrutop1
call LRUDelete
xor dx,dx ; DX == 0 means insert at head
call LRUInsert
glrutop1:
pop si
pop dx
pop bx
if KDEBUG
call check_lru_list
endif
ret
cEnd nogen
;-----------------------------------------------------------------------;
; glrubot ;
; ;
; Moves a discardable object to the tail of the LRU chain. ;
; ;
; Arguments: ;
; DS:DI = address of global heap info ;
; ES:DI = global arena of moveable object ;
; ;
; Returns: ;
; Updated LRU chain ;
; ;
; Error Returns: ;
; ;
; Registers Preserved: ;
; CX,DX,SI,DS,ES ;
; ;
; Registers Destroyed: ;
; ;
; Calls: ;
; ;
; History: ;
; ;
; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
; Added support for EMS. ;
; ;
; Mon Oct 27, 1986 04:20:10p -by- David N. Weise [davidw] ;
; Rewrote it to eliminate the handle table as intermediary. ;
;-----------------------------------------------------------------------;
cProc glrubot,<PUBLIC,NEAR>
cBegin nogen
push bx
push dx
push si
call glruSetup
jz glrubot1
call LRUDelete
mov dx,sp ; DX != 0 means insert at tail
call LRUInsert
glrubot1:
pop si
pop dx
pop bx
if KDEBUG
call check_lru_list
endif
ret
cEnd nogen
;-----------------------------------------------------------------------;
; glruadd ;
; ;
; Adds a discardable object to the head of the LRU chain. ;
; ;
; Arguments: ;
; DS:DI = address of global heap info ;
; ES:DI = arena header of object ;
; ;
; Returns: ;
; Updated LRU chain ;
; ;
; Error Returns: ;
; ;
; Registers Preserved: ;
; AX,BX,CX,DX,DI,SI,DS ;
; ;
; Registers Destroyed: ;
; none ;
; ;
; Calls: ;
; nothing ;
; ;
; History: ;
; ;
; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
; Added support for EMS. ;
; ;
; Mon Oct 27, 1986 04:23:35p -by- David N. Weise [davidw] ;
; Rewrote it to eliminate the handle table as intermediary. ;
;-----------------------------------------------------------------------;
cProc glruadd,<PUBLIC,NEAR>
cBegin nogen
push bx
push dx
push si
call glruSetup
jz glruadd1
xor dx,dx ; DX == 0 means insert at head
call LRUInsert
glruadd1:
pop si
pop dx
pop bx
if KDEBUG
call check_lru_list
endif
ret
cEnd nogen
;-----------------------------------------------------------------------;
; glrudel ;
; ;
; Removes a discardable object from the LRU chain. ;
; ;
; Arguments: ;
; ES:DI = arena header of object ;
; DS:DI = address of global heap info ;
; ;
; Returns: ;
; Nothing. ;
; ;
; Error Returns: ;
; ;
; Registers Preserved: ;
; All ;
; ;
; Registers Destroyed: ;
; ;
; Calls: ;
; ;
; History: ;
; ;
; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
; Added support for EMS. ;
; ;
; Mon Oct 27, 1986 04:36:49p -by- David N. Weise [davidw] ;
; Rewrote it to eliminate the handle table as intermediary. ;
;-----------------------------------------------------------------------;
cProc glrudel,<PUBLIC,NEAR>
cBegin nogen
push bx
push dx
push si
call glruSetup
jz glrudel1
call LRUDelete
glrudel1:
pop si
pop dx
pop bx
if KDEBUG
call check_lru_list
endif
ret
cEnd nogen
if KDEBUG
;-----------------------------------------------------------------------;
; check_lru_list ;
; ;
; Checks the glru list for consistency. ;
; ;
; Arguments: ;
; nothing ;
; ;
; Returns: ;
; ;
; Error Returns: ;
; ;
; Registers Preserved: ;
; All ;
; ;
; Registers Destroyed: ;
; ;
; Calls: ;
; nothing ;
; ;
; History: ;
; ;
; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
; Added support for EMS. ;
; ;
; Wed Oct 29, 1986 10:13:42a -by- David N. Weise [davidw] ;
; Wrote it. ;
;-----------------------------------------------------------------------;
cProc check_lru_list,<PUBLIC,NEAR>
cBegin nogen
push ds
SetKernelDS
test Kernel_flags,kf_check_free
jnz check_lru_too
jmps cll_ret
check_lru_too:
push ax
push bx
push cx
push dx
push es
mov ds,pGlobalHeap
UnSetKernelDS
xor bx,bx
do_it_again:
mov ax,[bx].gi_lruchain
mov cx,[bx].gi_lrucount ; without ems gi_alt_count is 0
or cx,cx
jnz short_relative_jumps
jmps all_done
short_relative_jumps:
push ds
push bx
mov es,ax
check_chain_loop:
mov ds,es:[di].ga_lruprev
mov es,es:[di].ga_lrunext
cmp ds:[di].ga_lrunext,ax
jz prev_okay
mov bx, ax
kerror 0FFh,<lru: prev bad>,ds,bx
mov ax, bx
prev_okay:
cmp es:[di].ga_lruprev,ax
jz next_okay
mov bx, ax
kerror 0FFh,<lru: next bad>,bx,es
next_okay:
mov ax,es
loop check_chain_loop
pop bx
pop ds
cmp [bx].gi_lruchain,ax
jz all_done
mov cx, ax
kerror 0FFh,<lru: count bad>,cx,[bx].gi_lrucount
all_done:
or bx,bx
jnz really_done
mov bx,gi_alt_lruchain - gi_lruchain
jmp do_it_again
really_done:
pop es
pop dx
pop cx
pop bx
pop ax
cll_ret:
pop ds
ret
cEnd nogen
endif
sEnd CODE
end