Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

593 lines
12 KiB

  1. TITLE GLRU - Primitives for LRU management
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include protect.inc
  7. .list
  8. .386p
  9. DataBegin
  10. externB Kernel_InDOS
  11. externB Kernel_flags
  12. ;externW curTDB
  13. externW loadTDB
  14. externW pGlobalHeap
  15. ;externW hExeSweep
  16. ;externW WinFlags
  17. if ROM
  18. externW gdtdsc
  19. endif
  20. DataEnd
  21. sBegin CODE
  22. assumes CS,CODE
  23. externNP DPMIProc
  24. ife ROM
  25. externW gdtdsc
  26. endif
  27. ;-----------------------------------------------------------------------;
  28. ; lrusweep ;
  29. ; ;
  30. ; Searches all of the exe headers in the system for segments that have ;
  31. ; been accessed since the last time through. For each segment found ;
  32. ; its referenced byte is reset and that segment is moved to the top ;
  33. ; of the lru chain. This routine is called (default) every 4 timer ;
  34. ; ticks from the int 8 handler. ;
  35. ; ;
  36. ; Arguments: ;
  37. ; none ;
  38. ; ;
  39. ; Returns: ;
  40. ; nothing ;
  41. ; ;
  42. ; Error Returns: ;
  43. ; ;
  44. ; Registers Preserved: ;
  45. ; DX,DI,SI,DS ;
  46. ; ;
  47. ; Registers Destroyed: ;
  48. ; AX,BX,CX,ES ;
  49. ; ;
  50. ; Calls: ;
  51. ; glrutop ;
  52. ; ;
  53. ; History: ;
  54. ; ;
  55. ; Tue Apr 21, 1987 06:22:41p -by- David N. Weise [davidw] ;
  56. ; Added the check for discarded segments. ;
  57. ; ;
  58. ; Wed Apr 08, 1987 11:00:59a -by- David N. Weise [davidw] ;
  59. ; Made it clear only the curTask's private handle table. ;
  60. ; ;
  61. ; Wed Feb 18, 1987 08:13:35p -by- David N. Weise [davidw] ;
  62. ; Added the sweeping of the private handle tables. ;
  63. ; ;
  64. ; Tue Feb 10, 1987 02:11:40a -by- David N. Weise [davidw] ;
  65. ; Added this nifty comment block. ;
  66. ;-----------------------------------------------------------------------;
  67. cProc lrusweep,<PUBLIC,FAR>
  68. cBegin nogen
  69. push edx
  70. push edi
  71. push esi
  72. push ds
  73. push es
  74. push fs
  75. xor edx,edx
  76. xor edi,edi
  77. SetKernelDS fs
  78. ; [notes from code review 4/91, added by donc 4/16/91
  79. ; 1) should check WinFlags1 for WF_PAGING,
  80. ; 2) insist on direct LDT access
  81. ; 3) try assembling without DPMI
  82. ; 4) have LRUSweepFreq= setting in .ini file to control update rate
  83. ; ]
  84. ; Excuses not to do the sweep:
  85. cmp kernel_InDOS,0 ; SMARTDrive and EMS may be present
  86. jnz short dont_do_it ; => disk buffers over the code segs
  87. cmp di,loadTDB ; Ignore interrupt if loading task
  88. jnz short dont_do_it
  89. mov ds,pGlobalHeap
  90. cmp di,ds:[di].gi_lrulock ; Ignore interrupt if inside memory
  91. jz short do_it ; manager
  92. dont_do_it:
  93. jmp sweepdone
  94. do_it:
  95. mov cx, ds:[di].gi_lrucount
  96. jcxz dont_do_it
  97. mov esi, ds:[di].gi_lruchain
  98. mov bx, gdtdsc
  99. or bx, bx ; See if we can poke at the LDT
  100. jz short sweep_loop_dpmi ; no, must use DPMI calls
  101. mov es, bx ; yes, ES points to the LDT
  102. ; Direct LDT access loop
  103. sweep_loop:
  104. mov esi, [esi].pga_lrunext
  105. mov bx, [esi].pga_handle
  106. sel_check bx
  107. if KDEBUG
  108. test es:[bx].dsc_hlimit, DSC_DISCARDABLE ; Ensure it really is discardable
  109. jnz short sweep_ok
  110. Debug_Out "lrusweep: Bad lru entry"
  111. sweep_ok:
  112. endif
  113. btr word ptr es:[bx].dsc_access, 0 ; Test and reset accessed bit
  114. .errnz DSC_ACCESSED-1
  115. jnc short sweep_next
  116. call glrutop ; Accessed objects are most recently used
  117. sweep_next:
  118. loop sweep_loop
  119. jmps sweepdone
  120. ; DPMI loop
  121. sweep_loop_dpmi:
  122. mov esi, [esi].pga_lrunext
  123. mov bx, [esi].pga_handle
  124. lar edx, ebx
  125. shr edx, 8 ; Access bits in DX
  126. if KDEBUG
  127. test dh, DSC_DISCARDABLE ; Ensure it really is discardable
  128. jnz short sweep_ok_dpmi
  129. Debug_Out "lrusweep: Bad lru entry"
  130. sweep_ok_dpmi:
  131. endif
  132. btr dx, 0 ; Segment accessed?
  133. .errnz DSC_ACCESSED-1
  134. jnc short sweep_next_dpmi ; no, leave it where it is on LRU list
  135. push cx
  136. mov cx, dx
  137. DPMICALL 0009h ; Set access word
  138. pop cx
  139. call glrutop ; Accessed objects are most recently used
  140. sweep_next_dpmi:
  141. loop sweep_loop_dpmi
  142. sweepdone:
  143. pop fs
  144. pop es
  145. pop ds
  146. pop esi
  147. pop edi
  148. pop edx
  149. ret
  150. UnSetKernelDS fs
  151. cEnd nogen
  152. ;
  153. ; Entry:
  154. ; DI == 0
  155. ; DS:SI.gi_lruchain -> head of list
  156. ; ES:0 -> arena header of object to insert
  157. ; DX = 0 => insert at head of list
  158. ; !=0 => insert at tail of list
  159. ;
  160. ; Exit:
  161. ; BX,DX destroyed
  162. ;
  163. cProc LRUInsert,<PUBLIC,NEAR>
  164. cBegin nogen
  165. inc ds:[di].gi_lrucount ; Increment count of LRU entries
  166. mov ebx,ds:[di].gi_lruchain ; BX = head of list
  167. or dx,dx ; Inserting at head of chain?
  168. jnz short lruins0 ; No, tail so dont update head
  169. mov ds:[di].gi_lruchain,esi ; Yes, make new one the new head
  170. lruins0:
  171. or ebx,ebx ; List empty?
  172. jnz short lruins1
  173. mov ds:[esi].pga_lruprev,esi; Yes, make circular
  174. mov ds:[esi].pga_lrunext,esi
  175. mov ds:[di].gi_lruchain,esi
  176. ret
  177. lruins1:
  178. mov edx,esi ; DX = new
  179. xchg ds:[ebx].pga_lruprev,edx
  180. mov ds:[edx].pga_lrunext,esi
  181. mov ds:[esi].pga_lruprev,edx
  182. mov ds:[esi].pga_lrunext,ebx
  183. ret
  184. cEnd nogen
  185. ;
  186. ; Entry:
  187. ; DI == 0
  188. ; DS:DI.gi_lruchain -> head of list
  189. ; DS_ESI -> arena header of object to delete
  190. ;
  191. ; Exit:
  192. ; EBX,EDX destroyed
  193. ;
  194. ;
  195. cProc LRUDelete,<PUBLIC,NEAR>
  196. cBegin nogen
  197. ;
  198. ; This is basically a consistency check, in case we don't fix
  199. ; GlobalRealloc() for 3.1.
  200. ;
  201. push eax
  202. mov eax,ds:[esi].pga_lrunext
  203. or eax,ds:[esi].pga_lruprev
  204. pop eax
  205. jz lrudel_ret
  206. dec ds:[di].gi_lrucount ; Decrement count of LRU entries
  207. jnz short lrudel0
  208. mov ds:[di].gi_lruchain,edi ; List empty, zero LRU chain.
  209. mov ds:[esi].pga_lruprev,edi; Zero pointers in deleted object
  210. mov ds:[esi].pga_lrunext,edi
  211. ret
  212. lrudel0:
  213. mov edx,esi
  214. cmp ds:[di].gi_lruchain,edx ; Are we deleting the head?
  215. jne short lrudel1
  216. mov edx,ds:[esi].pga_lrunext
  217. mov ds:[di].gi_lruchain,edx ; Yes, make it point to the next one
  218. lrudel1:
  219. xor ebx,ebx ; Zero pointers in deleted object
  220. xchg ds:[esi].pga_lrunext,ebx
  221. xor edx,edx
  222. xchg ds:[esi].pga_lruprev,edx
  223. mov ds:[edx].pga_lrunext,ebx
  224. mov ds:[ebx].pga_lruprev,edx
  225. lrudel_ret:
  226. ret
  227. cEnd nogen
  228. cProc glruSetup,<PUBLIC,NEAR>
  229. cBegin nogen
  230. mov bx,ds:[esi].pga_handle
  231. test bl, GA_FIXED
  232. jz short gsmoveable
  233. xor bx, bx ; Set ZF
  234. jmps gsdone
  235. gsmoveable:
  236. push ebx
  237. lar ebx, ebx
  238. test ebx, DSC_DISCARDABLE SHL 16
  239. pop ebx
  240. jz short gsdone
  241. or sp,sp
  242. gsdone:
  243. ret
  244. cEnd nogen
  245. ;-----------------------------------------------------------------------;
  246. ; glrutop ;
  247. ; ;
  248. ; Moves a discardable object to the head of the LRU chain. ;
  249. ; ;
  250. ; Arguments: ;
  251. ; DS:DI = address of global heap info ;
  252. ; ES:DI = global arena of moveable object ;
  253. ; ;
  254. ; Returns: ;
  255. ; Updated LRU chain ;
  256. ; ;
  257. ; Error Returns: ;
  258. ; ;
  259. ; Registers Preserved: ;
  260. ; CX,DX,SI,DS,ES ;
  261. ; ;
  262. ; Registers Destroyed: ;
  263. ; ;
  264. ; Calls: ;
  265. ; ;
  266. ; History: ;
  267. ; ;
  268. ; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
  269. ; Added support for EMS. ;
  270. ; ;
  271. ; Mon Oct 27, 1986 04:20:10p -by- David N. Weise [davidw] ;
  272. ; Rewrote it to eliminate the handle table as intermediary. ;
  273. ;-----------------------------------------------------------------------;
  274. cProc glrutop,<PUBLIC,NEAR>
  275. cBegin nogen
  276. push ebx
  277. push edx
  278. push esi
  279. call glruSetup
  280. jz short glrutop1
  281. call LRUDelete
  282. xor dx,dx ; DX == 0 means insert at head
  283. call LRUInsert
  284. glrutop1:
  285. pop esi
  286. pop edx
  287. pop ebx
  288. if KDEBUG
  289. call check_lru_list
  290. endif
  291. ret
  292. cEnd nogen
  293. ;-----------------------------------------------------------------------;
  294. ; glrubot ;
  295. ; ;
  296. ; Moves a discardable object to the tail of the LRU chain. ;
  297. ; ;
  298. ; Arguments: ;
  299. ; DS:DI = address of global heap info ;
  300. ; ES:DI = global arena of moveable object ;
  301. ; ;
  302. ; Returns: ;
  303. ; Updated LRU chain ;
  304. ; ;
  305. ; Error Returns: ;
  306. ; ;
  307. ; Registers Preserved: ;
  308. ; CX,DX,SI,DS,ES ;
  309. ; ;
  310. ; Registers Destroyed: ;
  311. ; ;
  312. ; Calls: ;
  313. ; ;
  314. ; History: ;
  315. ; ;
  316. ; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
  317. ; Added support for EMS. ;
  318. ; ;
  319. ; Mon Oct 27, 1986 04:20:10p -by- David N. Weise [davidw] ;
  320. ; Rewrote it to eliminate the handle table as intermediary. ;
  321. ;-----------------------------------------------------------------------;
  322. cProc glrubot,<PUBLIC,NEAR>
  323. cBegin nogen
  324. push bx
  325. push dx
  326. push si
  327. call glruSetup
  328. jz short glrubot1
  329. call LRUDelete
  330. mov dx,sp ; DX != 0 means insert at tail
  331. call LRUInsert
  332. glrubot1:
  333. pop si
  334. pop dx
  335. pop bx
  336. if KDEBUG
  337. call check_lru_list
  338. endif
  339. ret
  340. cEnd nogen
  341. ;-----------------------------------------------------------------------;
  342. ; glruadd ;
  343. ; ;
  344. ; Adds a discardable object to the head of the LRU chain. ;
  345. ; ;
  346. ; Arguments: ;
  347. ; DS:DI = address of global heap info ;
  348. ; ES:DI = arena header of object ;
  349. ; ;
  350. ; Returns: ;
  351. ; Updated LRU chain ;
  352. ; ;
  353. ; Error Returns: ;
  354. ; ;
  355. ; Registers Preserved: ;
  356. ; AX,BX,CX,DX,DI,SI,DS ;
  357. ; ;
  358. ; Registers Destroyed: ;
  359. ; none ;
  360. ; ;
  361. ; Calls: ;
  362. ; nothing ;
  363. ; ;
  364. ; History: ;
  365. ; ;
  366. ; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
  367. ; Added support for EMS. ;
  368. ; ;
  369. ; Mon Oct 27, 1986 04:23:35p -by- David N. Weise [davidw] ;
  370. ; Rewrote it to eliminate the handle table as intermediary. ;
  371. ;-----------------------------------------------------------------------;
  372. cProc glruadd,<PUBLIC,NEAR>
  373. cBegin nogen
  374. push bx
  375. push dx
  376. push si
  377. call glruSetup
  378. jz short glruadd1
  379. xor dx,dx ; DX == 0 means insert at head
  380. call LRUInsert
  381. glruadd1:
  382. pop si
  383. pop dx
  384. pop bx
  385. if KDEBUG
  386. call check_lru_list
  387. endif
  388. ret
  389. cEnd nogen
  390. ;-----------------------------------------------------------------------;
  391. ; glrudel ;
  392. ; ;
  393. ; Removes a discardable object from the LRU chain. ;
  394. ; ;
  395. ; Arguments: ;
  396. ; ES:DI = arena header of object ;
  397. ; DS:DI = address of global heap info ;
  398. ; ;
  399. ; Returns: ;
  400. ; Nothing. ;
  401. ; ;
  402. ; Error Returns: ;
  403. ; ;
  404. ; Registers Preserved: ;
  405. ; All ;
  406. ; ;
  407. ; Registers Destroyed: ;
  408. ; ;
  409. ; Calls: ;
  410. ; ;
  411. ; History: ;
  412. ; ;
  413. ; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
  414. ; Added support for EMS. ;
  415. ; ;
  416. ; Mon Oct 27, 1986 04:36:49p -by- David N. Weise [davidw] ;
  417. ; Rewrote it to eliminate the handle table as intermediary. ;
  418. ;-----------------------------------------------------------------------;
  419. cProc glrudel,<PUBLIC,NEAR>
  420. cBegin nogen
  421. push bx
  422. push dx
  423. push si
  424. call glruSetup
  425. jz short glrudel1
  426. call LRUDelete
  427. glrudel1:
  428. pop si
  429. pop dx
  430. pop bx
  431. if KDEBUG
  432. call check_lru_list
  433. endif
  434. ret
  435. cEnd nogen
  436. if KDEBUG
  437. ;-----------------------------------------------------------------------;
  438. ; check_lru_list ;
  439. ; ;
  440. ; Checks the glru list for consistency. ;
  441. ; ;
  442. ; Arguments: ;
  443. ; EDI 0 ;
  444. ; ;
  445. ; Returns: ;
  446. ; ;
  447. ; Error Returns: ;
  448. ; ;
  449. ; Registers Preserved: ;
  450. ; All ;
  451. ; ;
  452. ; Registers Destroyed: ;
  453. ; ;
  454. ; Calls: ;
  455. ; nothing ;
  456. ; ;
  457. ; History: ;
  458. ; ;
  459. ; Wed Feb 18, 1987 08:30:45p -by- David N. Weise [davidw] ;
  460. ; Added support for EMS. ;
  461. ; ;
  462. ; Wed Oct 29, 1986 10:13:42a -by- David N. Weise [davidw] ;
  463. ; Wrote it. ;
  464. ;-----------------------------------------------------------------------;
  465. cProc check_lru_list,<PUBLIC,NEAR>
  466. cBegin nogen
  467. push ds
  468. SetKernelDS
  469. test Kernel_flags,kf_check_free
  470. jz cll_ret
  471. push ax
  472. push ebx
  473. push cx
  474. push edx
  475. push esi
  476. mov ds,pGlobalHeap
  477. UnSetKernelDS
  478. do_it_again:
  479. mov ebx,[di].gi_lruchain
  480. mov cx,[di].gi_lrucount ; without ems gi_alt_count is 0
  481. or cx,cx
  482. jz all_done
  483. mov esi,ebx
  484. check_chain_loop:
  485. mov edx,ds:[esi].pga_lruprev
  486. mov esi,ds:[esi].pga_lrunext
  487. cmp ds:[edx].pga_lrunext,ebx
  488. jz short prev_okay
  489. kerror 0FFh,<lru: prev bad>,dx,bx
  490. prev_okay:
  491. cmp ds:[esi].pga_lruprev,ebx
  492. jz short next_okay
  493. kerror 0FFh,<lru: next bad>,bx,si
  494. next_okay:
  495. mov ebx,esi
  496. loop check_chain_loop
  497. cmp [di].gi_lruchain,ebx
  498. jz short all_done
  499. kerror 0FFh,<lru: count bad>,bx,[di].gi_lrucount
  500. all_done:
  501. pop esi
  502. pop edx
  503. pop cx
  504. pop ebx
  505. pop ax
  506. cll_ret:
  507. pop ds
  508. ret
  509. cEnd nogen
  510. endif
  511. sEnd CODE
  512. end