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.

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