Leaked source code of windows server 2003
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.

700 lines
18 KiB

  1. TITLE GMOREMEM - More Global Memory Manager procedures
  2. .xlist
  3. include kernel.inc
  4. include tdb.inc
  5. include newexe.inc
  6. .list
  7. include protect.inc
  8. .386p
  9. DataBegin
  10. externB Kernel_Flags
  11. externW pGlobalHeap
  12. externW curTDB
  13. externW headTDB
  14. externW Win_PDB
  15. externW MaxCodeSwapArea
  16. DataEnd
  17. sBegin CODE
  18. assumes CS,CODE
  19. assumes DS,NOTHING
  20. assumes ES,NOTHING
  21. if SDEBUG
  22. externNP DebugMovedSegment
  23. endif
  24. externNP gcompact
  25. externNP get_physical_address
  26. externNP GrowHeap
  27. externNP guncompact
  28. ;-----------------------------------------------------------------------;
  29. ; genter ;
  30. ; ;
  31. ; Enters a critical region for the global heap. ;
  32. ; ;
  33. ; Arguments: ;
  34. ; none ;
  35. ; ;
  36. ; Returns: ;
  37. ; DS:DI = address of GlobalInfo for global heap ;
  38. ; FS = Kernel Data segment ;
  39. ; ;
  40. ; Error Returns: ;
  41. ; ;
  42. ; Registers Preserved: ;
  43. ; All ;
  44. ; ;
  45. ; Registers Destroyed: ;
  46. ; ;
  47. ; Calls: ;
  48. ; ;
  49. ; History: ;
  50. ; ;
  51. ; Mon Sep 29, 1986 03:05:33p -by- David N. Weise [davidw] ;
  52. ; Added this nifty comment block. ;
  53. ;-----------------------------------------------------------------------;
  54. cProc genter,<PUBLIC,NEAR>
  55. cBegin nogen
  56. SetKernelDS FS
  57. mov ds,pGlobalHeap
  58. xor edi,edi
  59. inc [di].gi_lrulock
  60. ret
  61. UnSetKernelDS FS
  62. cEnd nogen
  63. ;-----------------------------------------------------------------------;
  64. ; gleave ;
  65. ; ;
  66. ; Leaves a critical region for the global heap. ;
  67. ; ;
  68. ; Arguments: ;
  69. ; DS:DI = address of GlobalInfo for global heap ;
  70. ; ;
  71. ; Returns: ;
  72. ; ;
  73. ; Error Returns: ;
  74. ; ;
  75. ; Registers Preserved: ;
  76. ; ;
  77. ; Registers Destroyed: ;
  78. ; ;
  79. ; Calls: ;
  80. ; ;
  81. ; History: ;
  82. ; ;
  83. ; Mon Sep 29, 1986 03:07:53p -by- David N. Weise [davidw] ;
  84. ; Added this nifty comment block. ;
  85. ;-----------------------------------------------------------------------;
  86. cProc gleave,<PUBLIC,NEAR>
  87. cBegin nogen
  88. dec ds:[gi_lrulock]
  89. jnz short gl_ret
  90. test ds:[gi_flags],GIF_INT2
  91. jz short gl_ret
  92. and ds:[gi_flags],NOT GIF_INT2
  93. int 02h
  94. gl_ret: ret
  95. cEnd nogen
  96. ;-----------------------------------------------------------------------;
  97. ; gavail ;
  98. ; ;
  99. ; Gets the available memory. ;
  100. ; ;
  101. ; Arguments: ;
  102. ; DX = number of paragraphs wanted ;
  103. ; DS:DI = master object ;
  104. ; Returns: ;
  105. ; AX = #paragraphs available for the biggest block ;
  106. ; DX = 0 ;
  107. ; ;
  108. ; Error Returns: ;
  109. ; none ;
  110. ; ;
  111. ; Registers Preserved: ;
  112. ; DI,DS ;
  113. ; Registers Destroyed: ;
  114. ; BX,CX,SI,ES ;
  115. ; Calls: ;
  116. ; gcompact ;
  117. ; ;
  118. ; History: ;
  119. ; Thu Apr 06, 1988 08:00:00a -by- Tim Halvorsen [iris] ;
  120. ; Fix bug in computation of space available when GA_NOT_THERE object ;
  121. ; resides above discard fence. ;
  122. ; ;
  123. ; Wed Oct 15, 1986 05:09:27p -by- David N. Weise [davidw] ;
  124. ; Moved he_count to ga_count. ;
  125. ; ;
  126. ; Sat Sep 27, 1986 09:37:27a -by- David N. Weise [davidw] ;
  127. ; Reworked it. ;
  128. ;-----------------------------------------------------------------------;
  129. cProc gavail,<PUBLIC,NEAR>
  130. cBegin nogen
  131. push esi
  132. push ecx
  133. mov byte ptr [di].gi_cmpflags,0
  134. call gcompact
  135. mov cx,word ptr [di].gi_disfence_hi ; ECX has address of fence
  136. shl ecx, 16
  137. mov cx,word ptr [di].gi_disfence_lo
  138. mov esi,[di].phi_first
  139. xor edx,edx
  140. loop_for_beginning:
  141. xor eax,eax
  142. mov esi,ds:[esi].pga_next ; Next block
  143. cmp ds:[esi].pga_sig,GA_ENDSIG ; End of arena?
  144. je all_done
  145. mov ebx, ds:[esi].pga_address
  146. add ebx, ds:[esi].pga_size ; End of block
  147. sub ebx, ecx ; Below fence?
  148. jbe short include_it ; yes, use it
  149. cmp ebx, ds:[di].gi_reserve ; Difference > reserve?
  150. jb all_done ; no, can't use it
  151. include_it:
  152. cmp ds:[esi].pga_owner,di ; Free?
  153. jz short how_big_is_it ; Yes calculate length
  154. cmp ds:[esi].pga_owner,GA_NOT_THERE ; Marker arena?
  155. jz short loop_for_beginning ; Yes, next block
  156. mov bx,ds:[esi].pga_handle
  157. test bl, GA_FIXED ; Fixed?
  158. jnz short loop_for_beginning ; Yes, next block
  159. cmp ds:[esi].pga_count,0 ; Locked?
  160. jne short loop_for_beginning ; Yes, next block
  161. lar ebx, ebx ; See lar docs and protect.inc
  162. test ebx, DSC_DISCARDABLE SHL 16 ; bit is in third byte of EBX
  163. jz short loop_for_beginning ; Not discardable, next block
  164. how_big_is_it:
  165. mov eax,ds:[esi].pga_size ; Use this size
  166. loop_for_bigness:
  167. mov esi,ds:[esi].pga_next ; Next block
  168. cmp ds:[esi].pga_owner,di ; Free?
  169. jz short include_his_size ; Yes, include size
  170. cmp ds:[esi].pga_owner,GA_NOT_THERE ; Marker arena?
  171. jz short end_of_bigness ; Yes
  172. cmp ds:[esi].pga_sig,GA_ENDSIG ; End of arena?
  173. jz short end_of_bigness
  174. mov bx,ds:[esi].pga_handle
  175. test bx,GA_FIXED ; Fixed?
  176. jnz short end_of_bigness ; Yes, stop looking
  177. cmp ds:[esi].pga_count,0 ; Locked?
  178. jne short end_of_bigness ; Yes, stop looking
  179. lar ebx, ebx ; See lar docs and protect.inc
  180. test ebx, DSC_DISCARDABLE SHL 16 ; bit is in third byte of EBX
  181. jz short loop_for_bigness ; No, dont include in count then
  182. include_his_size: ; Free or Discardable
  183. add eax,ds:[esi].pga_size ; Increase available space
  184. jmp loop_for_bigness
  185. end_of_bigness:
  186. mov esi, ds:[esi].pga_prev ; Get end of useable block
  187. mov ebx, ds:[esi].pga_address
  188. add ebx, ds:[esi].pga_size
  189. mov esi, ds:[esi].pga_next
  190. sub ebx, ecx ; Subtract fence
  191. jbe short all_below_fence
  192. cmp ebx, ds:[di].gi_reserve
  193. jae short all_below_fence
  194. sub eax,ebx ; We are above the fence, subtract
  195. ; that above the fence and say goodbye
  196. all_below_fence:
  197. cmp eax,edx ; Did we find a bigger block?
  198. jbe short blech_o_rama ; No, then look again
  199. mov edx,eax ; Yes, remember size
  200. blech_o_rama:
  201. jmp loop_for_beginning
  202. all_done:
  203. mov eax,edx
  204. sub eax, 20h ; Dont be too exact
  205. or eax,eax ; See if negative
  206. jns short gcfinal
  207. xor eax, eax ; Disallow negative returns
  208. gcfinal:
  209. and al,NOT 1Fh ; round down to nearest alignment
  210. xor dx,dx
  211. pop ecx
  212. pop esi
  213. ret
  214. cEnd nogen
  215. ;-----------------------------------------------------------------------;
  216. ; greserve ;
  217. ; ;
  218. ; Sets the size of the discardable code reserve area. ;
  219. ; If the new size is larger than the old size, it checks to see ;
  220. ; if there is enough room to support the new size. ;
  221. ; ;
  222. ; Arguments: ;
  223. ; AX = new greserve size ;
  224. ; ;
  225. ; Returns: ;
  226. ; CX = the largest greserve we can get ;
  227. ; AX != 0 success ;
  228. ; AX = 0 failure ;
  229. ; ;
  230. ; Error Returns: ;
  231. ; ;
  232. ; Registers Preserved: ;
  233. ; DI,SI,DS ;
  234. ; ;
  235. ; Registers Destroyed: ;
  236. ; BX,DX,ES ;
  237. ; ;
  238. ; Calls: ;
  239. ; genter ;
  240. ; gcompact ;
  241. ; will_gi_reserve_fit ;
  242. ; gleave ;
  243. ; ;
  244. ; History: ;
  245. ; Fri Jun 14, 1991 -by- Craig A. Critchley [craigc] ;
  246. ; Lots has happened since 1987 - undo change to get 128K always in ;
  247. ; enhanced mode ;
  248. ; ;
  249. ; Tue May 19, 1987 00:03:08p -by- David N. Weise [davidw] ;
  250. ; Made it far. ;
  251. ; ;
  252. ; Sat Sep 27, 1986 01:03:08p -by- David N. Weise [davidw] ;
  253. ; Made it perform according to spec and added this nifty comment block. ;
  254. ;-----------------------------------------------------------------------;
  255. assumes ds,nothing
  256. assumes es,nothing
  257. cProc greserve,<PUBLIC,FAR> ; FAR because of the gcompact below
  258. localD new_size
  259. cBegin
  260. GENTER32
  261. ReSetKernelDS FS
  262. movzx eax, ax
  263. shl eax, 4 ; convert to bytes
  264. mov ebx, eax
  265. shl eax, 1 ; double it
  266. add eax, ebx ; triple it!
  267. ; hold 3 64k segs for rep move case
  268. cmp eax, 030000h ; if >= 192K, THAT'S ENOUGH!
  269. jb short no_extra ; So there, Mr EXCEL!
  270. krDebugOut <DEB_TRACE OR DEB_KrMemMan>, "greserve: Who wants > 192K?"
  271. mov eax, 030000h
  272. no_extra:
  273. add eax,GA_ALIGN_BYTES
  274. and al,byte ptr GA_MASK_BYTES
  275. mov new_size,eax
  276. mov ebx,eax
  277. mov eax, ds:[di].phi_last
  278. mov eax, ds:[eax].pga_address
  279. sub eax,ebx ; Address of new gi_reserve
  280. cmp ebx, [di].gi_reserve ; New value <= old?
  281. ja short @F
  282. ;jmp new_okay
  283. ; never reduce the reserve to less than 192K!!!
  284. cmp ebx, 30000h
  285. jae new_okay
  286. ;krDebugOut <DEB_TRACE OR DEB_KrMemMan>, "greserve: Ignoring reduction of reserve area."
  287. or ax, 1 ; success code
  288. jmp gr_exit
  289. @@:
  290. if KDEBUG
  291. mov ecx, ebx
  292. shr ecx, 16
  293. krDebugOut <DEB_TRACE OR DEB_KrMemMan>, "greserve: #cx#BX bytes"
  294. endif
  295. call will_gi_reserve_fit
  296. jnc short new_okay
  297. push eax ; Must be junk in the way!
  298. push edx
  299. ; removed a compact here
  300. mov ecx, new_size
  301. call guncompact ; slide stuff down
  302. pop edx
  303. pop eax
  304. call will_gi_reserve_fit
  305. jnc short new_okay
  306. mov edx, new_size
  307. ;win95 has; or byte ptr fs:[Heap_Insert_Position], 1 ; insert at end
  308. call GrowHeap ; Assume this will insert new blk at end
  309. jc short will_not_fit
  310. mov eax, ds:[di].phi_last
  311. mov eax, ds:[eax].pga_address
  312. sub eax, new_size
  313. call will_gi_reserve_fit
  314. jnc short new_okay
  315. will_not_fit:
  316. if KDEBUG
  317. krDebugOut DEB_ERROR, "greserve doesn't fit"
  318. INT3_NEVER ; fixed at 192k, see ldboot.asm
  319. endif
  320. xor ax,ax
  321. jmps gr_exit
  322. new_okay:
  323. mov word ptr [di].gi_disfence_lo,ax
  324. shr eax, 16
  325. mov word ptr [di].gi_disfence_hi,ax
  326. mov edx,new_size
  327. mov [di].gi_reserve,edx
  328. or ax, 1 ; success code
  329. gr_exit:
  330. GLEAVE32
  331. UnSetKernelDS FS
  332. cEnd
  333. ;-----------------------------------------------------------------------;
  334. ; will_gi_reserve_fit ;
  335. ; ;
  336. ; See if new size okay by scanning arena backwards. If not under EMS ;
  337. ; this is trivial. With EMS we take into consideration the disjoint ;
  338. ; areas and the WRAITHS. ;
  339. ; ;
  340. ; Arguments: ;
  341. ; EAX = gi_disfence ;
  342. ; DS:DI = master object ;
  343. ; ;
  344. ; Returns: ;
  345. ; CF = 0 new size ok ;
  346. ; CF = 1 new size NOT ok ;
  347. ; ;
  348. ; Error Returns: ;
  349. ; ;
  350. ; Registers Preserved: ;
  351. ; AX,DX,DI,SI,DS ;
  352. ; ;
  353. ; Registers Destroyed: ;
  354. ; none ;
  355. ; ;
  356. ; Calls: ;
  357. ; nothing ;
  358. ; ;
  359. ; History: ;
  360. ; ;
  361. ; Sun Jul 12, 1987 08:13:23p -by- David N. Weise [davidw] ;
  362. ; Added EMS support. ;
  363. ; ;
  364. ; Sat Sep 27, 1986 01:03:57p -by- David N. Weise [davidw] ;
  365. ; Rewrote it. ;
  366. ;-----------------------------------------------------------------------;
  367. assumes ds, nothing
  368. assumes es, nothing
  369. cProc will_gi_reserve_fit,<PUBLIC,NEAR>
  370. cBegin nogen
  371. push esi
  372. mov esi, [di].phi_last
  373. mov esi, [esi].pga_prev ; skip sentinal
  374. does_it_fit:
  375. mov esi, [esi].pga_prev ; do first to skip nothere
  376. cmp [esi].pga_owner, di ; is it free?
  377. je short ok_thisll_fit
  378. test [esi].pga_flags, GA_DISCCODE ; is it code?
  379. jz short nope_wont_fit
  380. ok_thisll_fit:
  381. cmp eax, [esi].pga_address ; do we have enough
  382. jb short does_it_fit
  383. it_all_fits:
  384. clc ; return excellent!
  385. pop esi
  386. ret
  387. nope_wont_fit:
  388. stc ; return heinous!
  389. pop esi
  390. ret
  391. cEnd nogen
  392. ;-----------------------------------------------------------------------;
  393. ; gnotify ;
  394. ; ;
  395. ; This is where the hard job of updating the stacks and thunks happens. ;
  396. ; We only walk stacks and thunks for code and data (defined by being ;
  397. ; LocalInit'ed), not for resources or task allocated segments. ;
  398. ; ;
  399. ; Arguments: ;
  400. ; AL = message code ;
  401. ; BX = handle ;
  402. ; CX = optional argument ;
  403. ; ESI = address of arena header ;
  404. ; ;
  405. ; Returns: ;
  406. ; AX = return value from notify proc or AL ;
  407. ; DS = current DS (i.e. if DATA SEG was moved then DS is updated. ;
  408. ; ZF = 1 if AX = 0 ;
  409. ; ;
  410. ; Error Returns: ;
  411. ; ;
  412. ; Registers Preserved: ;
  413. ; DI,SI ;
  414. ; ;
  415. ; Registers Destroyed: ;
  416. ; BX,CX,DX,ES ;
  417. ; ;
  418. ; Calls: ;
  419. ; ;
  420. ; History: ;
  421. ; ;
  422. ; Wed Jun 24, 1987 03:08:39a -by- David N. Weise [davidw] ;
  423. ; Adding support for Global Notify. ;
  424. ; ;
  425. ; Wed Dec 03, 1986 01:59:27p -by- David N. Weise [davidw] ;
  426. ; Added this nifty comment block. ;
  427. ;-----------------------------------------------------------------------;
  428. cProc gnotify,<PUBLIC,NEAR>
  429. cBegin nogen
  430. push si
  431. push di
  432. xor ah,ah
  433. mov di,cx
  434. mov cx,ax
  435. loop notify_discard
  436. errnz <GN_MOVE - 1>
  437. mov cx,ds
  438. cmp cx,bx ; Did we move DS?
  439. jne short notify_exit_0 ; No, continue
  440. notify_exit_0:
  441. jmp notify_exit
  442. notify_discard:
  443. loop notify_exit_0
  444. errnz <GN_DISCARD - 2>
  445. ;-----------------------------------------------------------------------;
  446. ; Here for a segment discarded. ;
  447. ;-----------------------------------------------------------------------;
  448. xor ax,ax
  449. test bl,1
  450. jnz short notify_exit_0 ; SDK is wrong, can't free fixed.
  451. push ebx
  452. lar ebx, ebx ; See lar docs and protect.inc
  453. test ebx, DSC_DISCARDABLE SHL 16 ; bit is in third byte of EBX
  454. pop ebx
  455. jz short notify_exit_0
  456. test ds:[esi].pga_flags,GAH_NOTIFY
  457. jnz @F
  458. jmp dont_bother_asking
  459. @@:
  460. push bx
  461. push cx
  462. push dx
  463. mov ax,1
  464. mov es,ds:[esi].pga_owner
  465. cmp es:[ne_magic],NEMAGIC
  466. jz short dont_ask ; doesn't belong to a particular task
  467. mov ax,es
  468. SetKernelDS es
  469. push HeadTDB ; Look for TDB that owns this block.
  470. UnSetKernelDS es
  471. find_TDB:
  472. pop cx
  473. jcxz dont_ask
  474. mov es,cx
  475. push es:[TDB_next]
  476. cmp ax,es:[TDB_PDB]
  477. jnz short find_TDB
  478. pop cx ; clear stack in 1 byte
  479. mov cx,word ptr es:[TDB_GNotifyProc][0] ; paranoia
  480. or cx,word ptr es:[TDB_GNotifyProc][2]
  481. jz short dont_ask
  482. push ds
  483. SetKernelDS
  484. or Kernel_Flags[1],kf1_GLOBALNOTIFY
  485. push Win_PDB ; Save current PDB
  486. mov Win_PDB, ax ; Ensure it is the task's
  487. push fs
  488. push dword ptr es:[TDB_GNotifyProc]
  489. push bx ; push arg for notify proc
  490. mov ax,ss ; Zap segment regs so DS
  491. mov ds,ax ; doesn't get diddled by callee
  492. mov es,ax
  493. mov bx,sp
  494. call dword ptr ss:[bx]+2
  495. add sp,4 ; clean up stack.
  496. SetKernelDS
  497. and Kernel_Flags[1],not kf1_GLOBALNOTIFY
  498. pop fs
  499. pop Win_PDB ; Restore PDB
  500. pop ds
  501. UnSetKernelDS
  502. dont_ask:
  503. pop dx
  504. pop cx
  505. pop bx
  506. or ax,ax ; Well, can we?
  507. jz short notify_exit
  508. dont_bother_asking:
  509. mov es,ds:[esi].pga_owner
  510. cmp es:[ne_magic],NEMAGIC
  511. jnz short not_in_exe
  512. mov di,es:[ne_segtab]
  513. mov cx,es:[ne_cseg]
  514. jcxz not_in_exe
  515. pt0a:
  516. cmp bx,es:[di].ns_handle
  517. jz short pt0b
  518. add di,SIZE NEW_SEG1
  519. loop pt0a
  520. jmps not_in_exe
  521. pt0b:
  522. and byte ptr es:[di].ns_flags,not NSLOADED ; Mark as not loaded.
  523. not_in_exe:
  524. why_bother_again:
  525. xor di,di
  526. if SDEBUG
  527. cCall DebugMovedSegment,<si,di>
  528. endif
  529. mov ax,1
  530. notify_exit:
  531. or ax,ax
  532. pop di
  533. pop si
  534. ret
  535. gn_error:
  536. kerror 0FFh,<gnotify - cant discard segment>,si,si
  537. xor ax,ax
  538. jmp notify_exit
  539. cEnd nogen
  540. ;-----------------------------------------------------------------------;
  541. ; MemoryFreed ;
  542. ; ;
  543. ; This call is apps that have a GlobalNotify procedure. Some apps ;
  544. ; may shrink the segment instead of allowing it to be discarded, or ;
  545. ; they may free other blocks. This call tells the memory manager ;
  546. ; that some memory was freed somewhere. ;
  547. ; ;
  548. ; Arguments: ;
  549. ; WORD = # paragraphs freed ;
  550. ; ;
  551. ; Returns: ;
  552. ; DX:AX = amount of memory that still needs freeing ;
  553. ; ;
  554. ; Error Returns: ;
  555. ; ;
  556. ; Registers Preserved: ;
  557. ; ;
  558. ; Registers Destroyed: ;
  559. ; ;
  560. ; Calls: ;
  561. ; ;
  562. ; History: ;
  563. ; ;
  564. ; Fri 08-Apr-1988 10:25:55 -by- David N. Weise [davidw] ;
  565. ; Wrote it! ;
  566. ;-----------------------------------------------------------------------;
  567. cProc MemoryFreed,<PUBLIC,FAR>
  568. parmW memory_freed
  569. cBegin
  570. xor ax,ax
  571. SetKernelDS
  572. test Kernel_Flags[1],kf1_GLOBALNOTIFY
  573. jz short mf_done
  574. mov ds,pGlobalHeap
  575. UnSetKernelDS
  576. mov ax,memory_freed
  577. or ax,ax
  578. jz short mf_inquire
  579. or ds:[hi_ncompact],1 ; Remember we discarded something
  580. sub ds:[hi_distotal],ax ; Have we discarded enough yet?
  581. ja short mf_inquire
  582. or ds:[hi_ncompact],10h ; To tell gdiscard that we're done.
  583. mf_inquire:
  584. mov ax,ds:[hi_distotal] ; Have we discarded enough yet?
  585. mf_done:
  586. xor dx,dx
  587. cEnd
  588. ;-----------------------------------------------------------------------;
  589. ; SetSwapAreaSize ;
  590. ; ;
  591. ; Sets the current task's code swap area size. ;
  592. ; ;
  593. ; Arguments: ;
  594. ; WORD == 0 then current size is just returned ;
  595. ; != 0 number paragraphs wanted for swap area ;
  596. ; Returns: ;
  597. ; AX = Size actually set ;
  598. ; DX = Max size you can get ;
  599. ; ;
  600. ; Error Returns: ;
  601. ; ;
  602. ; Registers Preserved: ;
  603. ; ;
  604. ; Registers Destroyed: ;
  605. ; ;
  606. ; Calls: ;
  607. ; ;
  608. ; History: ;
  609. ; This API is history!!!! ;
  610. ; swap area is now fixed at 192k we don't grow or shrink it ;
  611. ; ;
  612. ;-----------------------------------------------------------------------;
  613. cProc SetSwapAreaSize,<PUBLIC,FAR>
  614. parmW nParas
  615. cBegin
  616. SetKernelDS
  617. mov dx,MaxCodeSwapArea
  618. mov ax,dx
  619. cEnd
  620. sEnd CODE
  621. end