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.

917 lines
21 KiB

  1. TITLE GMOREMEM - More Global Memory Manager procedures
  2. .xlist
  3. include kernel.inc
  4. include tdb.inc
  5. include newexe.inc
  6. include protect.inc
  7. .list
  8. .286
  9. DataBegin
  10. externB Kernel_Flags
  11. ;externW hGlobalHeap
  12. externW pGlobalHeap
  13. externW curTDB
  14. externW headTDB
  15. externW cur_dos_PDB
  16. externW Win_PDB
  17. externW MaxCodeSwapArea
  18. DataEnd
  19. externFP CalcMaxNRSeg
  20. sBegin CODE
  21. assumes CS,CODE
  22. assumes DS,NOTHING
  23. assumes ES,NOTHING
  24. ;externW MyCSDS
  25. if SDEBUG
  26. externNP DebugMovedSegment
  27. endif
  28. ;if SWAPPRO
  29. ;externNP WriteDiscardRecord
  30. ;endif
  31. externNP real_dos
  32. externNP gcompact
  33. externNP get_physical_address
  34. externNP get_arena_pointer
  35. externNP GetAccessWord
  36. externFP CVWBreak
  37. externNP GrowHeap
  38. if LDCHKSUM
  39. externNP ZeroSegmentChksum
  40. endif
  41. ;-----------------------------------------------------------------------;
  42. ; genter ;
  43. ; ;
  44. ; Enters a critical region for the global heap. ;
  45. ; ;
  46. ; Arguments: ;
  47. ; none ;
  48. ; ;
  49. ; Returns: ;
  50. ; DS:DI = address of GlobalInfo for global heap ;
  51. ; ;
  52. ; Error Returns: ;
  53. ; ;
  54. ; Registers Preserved: ;
  55. ; All ;
  56. ; ;
  57. ; Registers Destroyed: ;
  58. ; ;
  59. ; Calls: ;
  60. ; ;
  61. ; History: ;
  62. ; ;
  63. ; Mon Sep 29, 1986 03:05:33p -by- David N. Weise [davidw] ;
  64. ; Added this nifty comment block. ;
  65. ;-----------------------------------------------------------------------;
  66. cProc genter,<PUBLIC,NEAR>
  67. cBegin nogen
  68. SetKernelDS
  69. mov ds,pGlobalHeap
  70. UnSetKernelDS
  71. xor di,di
  72. inc [di].gi_lrulock
  73. ret
  74. cEnd nogen
  75. ;-----------------------------------------------------------------------;
  76. ; gleave ;
  77. ; ;
  78. ; Leaves a critical region for the global heap. ;
  79. ; ;
  80. ; Arguments: ;
  81. ; DS:DI = address of GlobalInfo for global heap ;
  82. ; ;
  83. ; Returns: ;
  84. ; ;
  85. ; Error Returns: ;
  86. ; ;
  87. ; Registers Preserved: ;
  88. ; ;
  89. ; Registers Destroyed: ;
  90. ; ;
  91. ; Calls: ;
  92. ; ;
  93. ; History: ;
  94. ; ;
  95. ; Mon Sep 29, 1986 03:07:53p -by- David N. Weise [davidw] ;
  96. ; Added this nifty comment block. ;
  97. ;-----------------------------------------------------------------------;
  98. cProc gleave,<PUBLIC,NEAR>
  99. cBegin nogen
  100. dec ds:[gi_lrulock]
  101. jnz gl_ret
  102. test ds:[gi_flags],GIF_INT2
  103. jz gl_ret
  104. and ds:[gi_flags],NOT GIF_INT2
  105. pushf
  106. call CVWBreak
  107. gl_ret: ret
  108. cEnd nogen
  109. ;-----------------------------------------------------------------------;
  110. ; gavail ;
  111. ; ;
  112. ; Gets the available memory. ;
  113. ; ;
  114. ; Arguments: ;
  115. ; DX = number of paragraphs wanted ;
  116. ; DS:DI = master object ;
  117. ; Returns: ;
  118. ; AX = #paragraphs available for the biggest block ;
  119. ; DX = 0 ;
  120. ; ;
  121. ; Error Returns: ;
  122. ; none ;
  123. ; ;
  124. ; Registers Preserved: ;
  125. ; DI,DS ;
  126. ; Registers Destroyed: ;
  127. ; BX,CX,SI,ES ;
  128. ; Calls: ;
  129. ; gcompact ;
  130. ; ;
  131. ; History: ;
  132. ; Thu Apr 06, 1988 08:00:00a -by- Tim Halvorsen [iris] ;
  133. ; Fix bug in computation of space available when GA_NOT_THERE object ;
  134. ; resides above discard fence. ;
  135. ; ;
  136. ; Wed Oct 15, 1986 05:09:27p -by- David N. Weise [davidw] ;
  137. ; Moved he_count to ga_count. ;
  138. ; ;
  139. ; Sat Sep 27, 1986 09:37:27a -by- David N. Weise [davidw] ;
  140. ; Reworked it. ;
  141. ;-----------------------------------------------------------------------;
  142. cProc gavail,<PUBLIC,NEAR>
  143. cBegin nogen
  144. mov byte ptr [di].gi_cmpflags,0
  145. call gcompact
  146. mov es,[di].hi_first
  147. xor dx,dx
  148. loop_for_beginning:
  149. xor ax,ax
  150. mov es,es:[di].ga_next ; Next block
  151. cmp es:[di].ga_sig,GA_ENDSIG ; End of arena?
  152. jnz blecher
  153. jmp all_done
  154. blecher:
  155. cmp es:[di].ga_owner,di ; Free?
  156. jz how_big_is_it ; Yes
  157. mov si,es:[di].ga_handle
  158. or si,si ; Fixed?
  159. jz loop_for_beginning ; Yes, next block
  160. cmp es:[di].ga_count,0 ; Locked?
  161. jne loop_for_beginning ; Yes, next block
  162. push ax
  163. cCall GetAccessWord,<si>
  164. test ah, DSC_DISCARDABLE
  165. pop ax
  166. jz loop_for_beginning ; No, next block
  167. how_big_is_it:
  168. mov ax,es:[di].ga_size ; Use this size
  169. loop_for_bigness:
  170. mov es,es:[di].ga_next ; Next block
  171. cmp es:[di].ga_owner,di ; Free?
  172. jz include_his_size ; Yes, include size
  173. cmp es:[di].ga_sig,GA_ENDSIG ; End of arena?
  174. jz all_done
  175. mov si,es:[di].ga_handle
  176. or si,si ; Fixed?
  177. jz end_of_bigness ; Yes, stop looking
  178. cmp es:[di].ga_count,0 ; Locked?
  179. jne end_of_bigness ; Yes, stop looking
  180. push ax
  181. cCall GetAccessWord,<si>
  182. test ah, DSC_DISCARDABLE
  183. pop ax
  184. jz dont_include_him ; No, dont include in count then
  185. include_his_size: ; Free or Discardable
  186. add ax,es:[di].ga_size ; Increase availabe space
  187. inc ax ; by size of this block
  188. dont_include_him: ; Moveable
  189. jmp loop_for_bigness
  190. end_of_bigness:
  191. mov si,es
  192. cmp es:[di].ga_owner,GA_NOT_THERE
  193. jnz nothing_not_there
  194. push ax
  195. push dx
  196. cCall get_physical_address,<si>
  197. sub ax,word ptr [di].gi_disfence_lo
  198. sbb dx,word ptr [di].gi_disfence_hi
  199. jae fence_lower
  200. pop dx
  201. pop ax
  202. jmps nothing_not_there
  203. fence_lower:
  204. REPT 4
  205. shr dx,1
  206. rcr ax,1
  207. ENDM
  208. mov si,ax
  209. pop dx
  210. pop ax
  211. sub ax,si
  212. jmps all_done_1
  213. nothing_not_there:
  214. cmp ax,dx ; Did we find a bigger block?
  215. jbe blech_o_rama ; No, then look again
  216. mov dx,ax ; Yes, remember size
  217. blech_o_rama:
  218. jmp loop_for_beginning
  219. all_done:
  220. sub ax,[di].gi_reserve ; In case lower_land has little free.
  221. jb all_done_2
  222. all_done_1:
  223. cmp ax,dx ; Did we find a bigger block?
  224. ja gcsize
  225. all_done_2:
  226. mov ax,dx
  227. gcsize:
  228. inc ax ; Cheap bug fix
  229. or ax,ax ; zero mem available?
  230. jz gcfinal ; yes, return 0
  231. dec ax ; Dont be too exact
  232. jz gcfinal
  233. dec ax
  234. jz gcfinal
  235. dec ax
  236. gcfinal:
  237. and al,GA_MASK ; round down to nearest alignment
  238. xor dx,dx
  239. ret
  240. cEnd nogen
  241. ;-----------------------------------------------------------------------;
  242. ; greserve ;
  243. ; ;
  244. ; Sets the size of the discardable code reserve area. ;
  245. ; If the new size is larger than the old size, it checks to see ;
  246. ; if there is enough room to support the new size. ;
  247. ; ;
  248. ; Arguments: ;
  249. ; AX = new greserve size ;
  250. ; ;
  251. ; Returns: ;
  252. ; CX = the largest greserve we can get ;
  253. ; AX != 0 success ;
  254. ; AX = 0 failure ;
  255. ; ;
  256. ; Error Returns: ;
  257. ; ;
  258. ; Registers Preserved: ;
  259. ; DI,SI,DS ;
  260. ; ;
  261. ; Registers Destroyed: ;
  262. ; BX,DX,ES ;
  263. ; ;
  264. ; Calls: ;
  265. ; genter ;
  266. ; gcompact ;
  267. ; will_gi_reserve_fit ;
  268. ; gleave ;
  269. ; ;
  270. ; History: ;
  271. ; ;
  272. ; Sun 14-Jan-1990 13:42:59 -by- David N. Weise [davidw] ;
  273. ; The greserve must be twice as big as the largest non-resident ;
  274. ; segment, because restarting a NP fault requires both caller and ;
  275. ; callee to be in memory. ;
  276. ; ;
  277. ; Tue May 19, 1987 00:03:08p -by- David N. Weise [davidw] ;
  278. ; Made it far. ;
  279. ; ;
  280. ; Sat Sep 27, 1986 01:03:08p -by- David N. Weise [davidw] ;
  281. ; Made it perform according to spec and added this nifty comment block. ;
  282. ;-----------------------------------------------------------------------;
  283. assumes ds,nothing
  284. assumes es,nothing
  285. cProc greserve,<PUBLIC,FAR>,<si,di> ; FAR because of the gcompact below
  286. localW new_size
  287. cBegin
  288. call genter
  289. add ax, ax ; Double required so caller & callee
  290. add ax,GA_ALIGN ; both fit in memory
  291. and al,GA_MASK
  292. mov new_size,ax
  293. mov si, ax
  294. mov cx,[di].gi_reserve ; Get old size.
  295. jcxz first_time ; Old size equal to zero?
  296. call will_gi_reserve_fit
  297. jnc new_okay
  298. call GrowHeap
  299. call will_gi_reserve_fit
  300. jnc new_okay
  301. try_compacting:
  302. mov dx,new_size
  303. call gcompact ; Try compacting to get new reserve
  304. call will_gi_reserve_fit
  305. jnc new_okay
  306. will_not_fit:
  307. xor ax,ax
  308. jmps gr_exit
  309. first_time: ; Things are strange at first
  310. mov bx, ax
  311. xor cx, cx
  312. REPT 4
  313. shl bx, 1
  314. rcl cx, 1
  315. ENDM
  316. cCall get_physical_address,<[di].hi_last>
  317. sub ax, bx
  318. sbb dx, cx ; Address of gi_reserve
  319. new_okay:
  320. mov word ptr [di].gi_disfence_lo,ax
  321. mov word ptr [di].gi_disfence_hi,dx
  322. mov dx,new_size
  323. mov [di].gi_reserve,dx
  324. gr_exit:
  325. call gleave
  326. cEnd
  327. ;-----------------------------------------------------------------------;
  328. ; will_gi_reserve_fit ;
  329. ; ;
  330. ; See if new size okay by scanning arena backwards. ;
  331. ; ;
  332. ; Arguments: ;
  333. ; SI = new greserve size ;
  334. ; DS:DI = master object ;
  335. ; ;
  336. ; Returns: ;
  337. ; DX:AX = gi_disfence ;
  338. ; BX = amount of NOT THERE memory, such as EGA ;
  339. ; CX = the largest greserve we can get ;
  340. ; CF = 0 new size ok ;
  341. ; CF = 1 new size NOT ok ;
  342. ; ES:DI => arena below CODE segments ;
  343. ; ;
  344. ; Error Returns: ;
  345. ; ;
  346. ; Registers Preserved: ;
  347. ; SI,DI,DS ;
  348. ; ;
  349. ; Registers Destroyed: ;
  350. ; ;
  351. ; ;
  352. ; Calls: ;
  353. ; nothing ;
  354. ; ;
  355. ; History: ;
  356. ; ;
  357. ; Sun Jul 12, 1987 08:13:23p -by- David N. Weise [davidw] ;
  358. ; Added EMS support. ;
  359. ; ;
  360. ; Sat Sep 27, 1986 01:03:57p -by- David N. Weise [davidw] ;
  361. ; Rewrote it. ;
  362. ;-----------------------------------------------------------------------;
  363. cProc will_gi_reserve_fit,<PUBLIC,NEAR>
  364. localB got_half
  365. localW second_block
  366. localW largest_block
  367. localW fence_block
  368. localW fence_offset
  369. cBegin
  370. xor ax,ax
  371. xor bx,bx
  372. mov got_half, al
  373. mov fence_block, ax
  374. mov largest_block, ax
  375. mov second_block, ax
  376. mov es,[di].hi_last
  377. mov cx,[di].hi_count
  378. how_much_space_loop:
  379. mov es,es:[di].ga_prev
  380. how_much_space_loop1:
  381. cmp di,es:[di].ga_owner ; If free then include.
  382. jz include_this_one
  383. test es:[di].ga_flags,GA_DISCCODE ; If disccode then include.
  384. jz end_block
  385. include_this_one:
  386. add ax, es:[di].ga_size ; Total the size of this block
  387. inc ax ; include arena header
  388. loop how_much_space_loop
  389. end_block:
  390. cmp ax, largest_block ; Track two largest blocks
  391. jbe not_largest
  392. push largest_block
  393. mov largest_block, ax
  394. pop second_block
  395. jmps not_second
  396. not_largest:
  397. cmp ax, second_block
  398. jbe not_second
  399. mov second_block, ax
  400. not_second:
  401. cmp fence_block, di
  402. jne skip_not_there
  403. cmp si, ax ; This block big enough?
  404. jbe set_fence
  405. cmp got_half, 0
  406. jne skip_not_there ; Already split requirement
  407. shr si, 1
  408. cmp si, ax ; Half fits?
  409. ja no_good
  410. mov got_half, 1 ; yes, will use this block
  411. jmps skip_not_there
  412. set_fence:
  413. sub ax, si
  414. mov fence_offset, ax ; Offset from next arena
  415. mov ax, es:[di].ga_next
  416. mov fence_block, ax
  417. jmps skip_not_there
  418. no_good:
  419. shl si, 1 ; no, keep trying for full amount
  420. skip_not_there:
  421. xor ax, ax ; zero count
  422. cmp es:[di].ga_owner,GA_NOT_THERE
  423. jne thats_all_folks
  424. skip_not_there_loop:
  425. add bx,es:[di].ga_size
  426. dec cx
  427. mov es, es:[di].ga_prev
  428. cmp es:[di].ga_owner, GA_NOT_THERE ; skip all not there blocks
  429. je skip_not_there_loop
  430. jmps how_much_space_loop1
  431. thats_all_folks:
  432. mov cx, second_block ; Return max of twice second
  433. shl cx, 1 ; largest block and the largest
  434. jnc not_monstrously_huge ; block
  435. mov cx, 0FFFDh
  436. jmps time_to_go
  437. not_monstrously_huge:
  438. cmp cx, largest_block
  439. jae time_to_go
  440. mov cx, largest_block
  441. time_to_go:
  442. cmp got_half, 1
  443. jne si_ok
  444. shl si, 1
  445. si_ok:
  446. cmp cx, si ; Set CARRY for failure
  447. jc failed
  448. push bx
  449. push cx
  450. cCall get_physical_address,<fence_block>
  451. mov bx, fence_offset
  452. xor cx, cx
  453. REPT 4
  454. shl bx, 1
  455. rcl cx, 1
  456. ENDM
  457. add ax, bx
  458. adc dx, cx ; DX:AX is new fence
  459. pop cx
  460. pop bx
  461. clc ; Success
  462. failed:
  463. cEnd
  464. ;-----------------------------------------------------------------------;
  465. ; gnotify ;
  466. ; ;
  467. ; This is where the hard job of updating the stacks and thunks happens. ;
  468. ; We only walk stacks and thunks for code and data (defined by being ;
  469. ; LocalInit'ed), not for resources or task allocated segments. ;
  470. ; ;
  471. ; Arguments: ;
  472. ; AL = message code ;
  473. ; BX = handle ;
  474. ; CX = optional argument ;
  475. ; ES = address of arena header ;
  476. ; ;
  477. ; Returns: ;
  478. ; AX = return value from notify proc or AL ;
  479. ; DS = current DS (i.e. if DATA SEG was moved then DS is updated. ;
  480. ; ZF = 1 if AX = 0 ;
  481. ; ;
  482. ; Error Returns: ;
  483. ; ;
  484. ; Registers Preserved: ;
  485. ; DI,SI ;
  486. ; ;
  487. ; Registers Destroyed: ;
  488. ; BX,CX,DX,ES ;
  489. ; ;
  490. ; Calls: ;
  491. ; ;
  492. ; History: ;
  493. ; ;
  494. ; Wed Jun 24, 1987 03:08:39a -by- David N. Weise [davidw] ;
  495. ; Adding support for Global Notify. ;
  496. ; ;
  497. ; Wed Dec 03, 1986 01:59:27p -by- David N. Weise [davidw] ;
  498. ; Added this nifty comment block. ;
  499. ;-----------------------------------------------------------------------;
  500. cProc gnotify,<PUBLIC,NEAR>
  501. cBegin nogen
  502. push si
  503. push di
  504. xor ah,ah
  505. mov di,cx
  506. mov cx,ax
  507. mov si,bx
  508. loop notify_discard
  509. errnz <GN_MOVE - 1>
  510. ;-----------------------------------------------------------------------;
  511. ; Here for a segment that moved. ;
  512. ;-----------------------------------------------------------------------;
  513. why_bother:
  514. mov cx,ds
  515. cmp cx,si ; Did we move DS?
  516. jne notify_exit_0 ; No, continue
  517. notify_exit_0:
  518. jmp notify_exit
  519. notify_discard:
  520. ;;;;;; loop notify_exit
  521. loop notify_exit_0
  522. errnz <GN_DISCARD - 2>
  523. ;-----------------------------------------------------------------------;
  524. ; Here for a segment discarded. ;
  525. ;-----------------------------------------------------------------------;
  526. xor ax,ax
  527. test bl,1
  528. jnz notify_exit_0 ; SDK is wrong, can't free fixed.
  529. push ax
  530. cCall GetAccessWord,<bx>
  531. test ah, DSC_DISCARDABLE
  532. pop ax
  533. jz notify_exit_0
  534. test es:[ga_flags],GAH_NOTIFY
  535. jnz @F
  536. jmp dont_bother_asking
  537. @@:
  538. push bx
  539. push cx
  540. push dx
  541. mov ax,1
  542. mov es,es:[ga_owner]
  543. cmp es:[ne_magic],NEMAGIC
  544. jz dont_ask ; doesn't belong to a particular task
  545. mov ax,es
  546. SetKernelDS es
  547. push HeadTDB ; Look for TDB that owns this block.
  548. find_TDB:
  549. pop cx
  550. jcxz dont_ask
  551. mov es,cx
  552. UnSetKernelDS es
  553. push es:[TDB_next]
  554. cmp ax,es:[TDB_PDB]
  555. jnz find_TDB
  556. pop cx ; clear stack in 1 byte
  557. mov cx,word ptr es:[TDB_GNotifyProc][0] ; paranoia
  558. cmp cx,word ptr es:[TDB_GNotifyProc][2]
  559. jz dont_ask
  560. push ds
  561. SetKernelDS
  562. ;;; xor cx, cx ; bad Hack for Legend
  563. ;;; cmp ax, cur_dos_PDB ; Are we on task's PDB
  564. ;;; je nothing_to_hack ; Yes, fine
  565. ;;; mov cx, cur_dos_PDB ; No, save the PDB to restore
  566. ;;; push ax
  567. ;;; push bx
  568. ;;; mov bx, ax
  569. ;;; mov cur_dos_PDB, bx ; And point us to the task's
  570. ;;; mov Win_PDB, bx
  571. ;;; mov ah, 50h
  572. ;;; call real_dos
  573. ;;; pop bx
  574. ;;; pop ax
  575. ;;;nothing_to_hack:
  576. ;;; push cx ; Save old PDB (if any)
  577. push Win_PDB ; Save current PDB
  578. mov Win_PDB, ax ; Ensure it is the task's
  579. or Kernel_Flags[1],kf1_GLOBALNOTIFY
  580. push es:[TDB_GNotifyProc]+2 ; push addr of func to call onto stack
  581. push es:[TDB_GNotifyProc]
  582. push bx ; push arg for notify proc
  583. mov ax,ss ; Zap segment regs so DS
  584. mov ds,ax ; doesn't get diddled by callee
  585. mov es,ax
  586. mov bx,sp
  587. call dword ptr ss:[bx]+2
  588. add sp,4 ; clean up stack.
  589. SetKernelDS
  590. and Kernel_Flags[1],not kf1_GLOBALNOTIFY
  591. pop Win_PDB ; Restore PDB
  592. ;;; pop bx ; Saved PDB
  593. ;;; or bx, bx ; Was there one?
  594. ;;; jz @F ; Nope.
  595. ;;; push ax
  596. ;;; mov ah, 50h ; Set it back...
  597. ;;; mov cur_dos_PDB, bx
  598. ;;; mov Win_PDB, bx
  599. ;;; call real_dos
  600. ;;; pop ax
  601. ;;;@@:
  602. pop ds
  603. UnSetKernelDS
  604. dont_ask:
  605. pop dx
  606. pop cx
  607. pop bx
  608. or ax,ax ; Well, can we?
  609. jz notify_exit
  610. dont_bother_asking:
  611. cCall get_arena_pointer,<si>
  612. mov es,ax
  613. mov es,es:[ga_owner]
  614. cmp es:[ne_magic],NEMAGIC
  615. jnz not_in_exe
  616. mov di,es:[ne_segtab]
  617. mov cx,es:[ne_cseg]
  618. jcxz not_in_exe
  619. ; test es:[ne_flags],NENOTP
  620. ; jnz pt0a
  621. ; inc bx
  622. pt0a:
  623. cmp bx,es:[di].ns_handle
  624. jz pt0b
  625. add di,SIZE NEW_SEG1
  626. loop pt0a
  627. jmps not_in_exe
  628. pt0b:
  629. and byte ptr es:[di].ns_flags,not NSLOADED ; Mark as not loaded.
  630. not_in_exe:
  631. why_bother_again:
  632. xor di,di
  633. if SDEBUG
  634. cCall DebugMovedSegment,<si,di>
  635. endif
  636. if LDCHKSUM
  637. call ZeroSegmentChksum ; SI points to segment
  638. endif
  639. mov ax,1
  640. notify_exit:
  641. or ax,ax
  642. pop di
  643. pop si
  644. ret
  645. gn_error:
  646. kerror 0FFh,<gnotify - cant discard segment>,si,si
  647. xor ax,ax
  648. jmp notify_exit
  649. cEnd nogen
  650. ;-----------------------------------------------------------------------;
  651. ; MemoryFreed ;
  652. ; ;
  653. ; This call is apps that have a GlobalNotify procedure. Some apps ;
  654. ; may shrink the segment instead of allowing it to be discarded, or ;
  655. ; they may free other blocks. This call tells the memory manager ;
  656. ; that some memory was freed somewhere. ;
  657. ; ;
  658. ; Arguments: ;
  659. ; WORD = # paragraphs freed ;
  660. ; ;
  661. ; Returns: ;
  662. ; DX:AX = amount of memory that still needs freeing ;
  663. ; ;
  664. ; Error Returns: ;
  665. ; ;
  666. ; Registers Preserved: ;
  667. ; ;
  668. ; Registers Destroyed: ;
  669. ; ;
  670. ; Calls: ;
  671. ; ;
  672. ; History: ;
  673. ; ;
  674. ; Fri 08-Apr-1988 10:25:55 -by- David N. Weise [davidw] ;
  675. ; Wrote it! ;
  676. ;-----------------------------------------------------------------------;
  677. cProc MemoryFreed,<PUBLIC,FAR>
  678. parmW memory_freed
  679. cBegin
  680. xor ax,ax
  681. SetKernelDS
  682. test Kernel_Flags[1],kf1_GLOBALNOTIFY
  683. jz mf_done
  684. mov ds,pGlobalHeap
  685. UnSetKernelDS
  686. mov ax,memory_freed
  687. or ax,ax
  688. jz mf_inquire
  689. or ds:[hi_ncompact],1 ; Remember we discarded something
  690. sub ds:[hi_distotal],ax ; Have we discarded enough yet?
  691. ja mf_inquire
  692. or ds:[hi_ncompact],10h ; To tell gdiscard that we're done.
  693. mf_inquire:
  694. mov ax,ds:[hi_distotal] ; Have we discarded enough yet?
  695. mf_done:
  696. xor dx,dx
  697. cEnd
  698. ;-----------------------------------------------------------------------;
  699. ; SetSwapAreaSize ;
  700. ; ;
  701. ; Sets the current task's code swap area size. ;
  702. ; ;
  703. ; Arguments: ;
  704. ; WORD == 0 then current size is just returned ;
  705. ; != 0 number paragraphs wanted for swap area ;
  706. ; Returns: ;
  707. ; AX = Size actually set ;
  708. ; DX = Max size you can get ;
  709. ; ;
  710. ; Error Returns: ;
  711. ; ;
  712. ; Registers Preserved: ;
  713. ; ;
  714. ; Registers Destroyed: ;
  715. ; ;
  716. ; Calls: ;
  717. ; ;
  718. ; History: ;
  719. ; ;
  720. ; Thu Apr 18, 1988 08:00:00a -by- T.H. SpeedWagon [-????-] ;
  721. ; Move routine into CODE segment, so applications can query the ;
  722. ; code working set value without paging in the NRESCODE segment. ;
  723. ; ;
  724. ; Thu Apr 23, 1987 09:36:00p -by- R.E.O. SpeedWagon [-???-] ;
  725. ; Added ability to get size without setting it. ;
  726. ; ;
  727. ; Wed Dec 03, 1986 10:52:16p -by- David N. Weise [davidw] ;
  728. ; Rewrote it. ;
  729. ;-----------------------------------------------------------------------;
  730. cProc SetSwapAreaSize,<PUBLIC,FAR>
  731. parmW nParas
  732. localW MxCodeSwapArea
  733. cBegin
  734. SetKernelDS
  735. mov ax,nParas
  736. xor bx,bx
  737. mov cx,MaxCodeSwapArea
  738. mov MxCodeSwapArea,cx ; avoid a segment load later
  739. cmp ax,cx
  740. jbe requested_size_OK
  741. mov ax,cx
  742. requested_size_OK:
  743. mov ds,CurTDB
  744. UnSetKernelDS
  745. mov ds,ds:[bx].TDB_pModule ; Get exe header address
  746. or ax,ax ; just a query request?
  747. jz got_it ; yes
  748. cmp ax,ds:[bx].ne_swaparea
  749. jz got_it ; just want what we have?
  750. ja calc_it
  751. ; To restart a NP fault both caller and callee must be in memory.
  752. ; So we cheat here, and set the minimum to be twice the rmode number.
  753. ; We have to prevent the app from setting the swap area too
  754. ; small. So we recalculate the minimum needed. We should
  755. ; do this is rmode as well, but the chance of messing up is
  756. ; much larger in pmode, where new app writers are apt to
  757. ; be very cavalier with lots of memory.
  758. ; We should keep another NE variable instead of always
  759. ; recalculating the largest ne_seg BUT at this late
  760. ; date this is simpler!
  761. push ax
  762. xor ax,ax ; No max yet.
  763. mov cx,ds:[bx].ne_cseg
  764. mov bx,ds:[bx].ne_segtab
  765. jcxz no_NR_segments
  766. get_largest_loop:
  767. test ds:[bx].ns_flags,NSDATA ; Code segment?
  768. jnz not_disc_code
  769. .errnz NSCODE
  770. test ds:[bx].ns_flags,NSDISCARD ; Discardable?
  771. jz not_disc_code ; No, ignore.
  772. mov dx,ds:[bx].ns_minalloc ; Yes, get size
  773. add dx,0Fh ; in paragraphs
  774. shr dx,4
  775. cmp ax,dx ; Biggest NR Seg?
  776. jae not_disc_code
  777. mov ax,dx
  778. not_disc_code:
  779. add bx,SIZE NEW_SEG1
  780. loop get_largest_loop
  781. no_NR_segments:
  782. shl ax,1
  783. mov cx,ax
  784. pop ax
  785. cmp ax,cx
  786. ja calc_it
  787. mov ax,cx
  788. calc_it:
  789. xchg ds:[ne_swaparea],ax
  790. push ax
  791. call CalcMaxNRSeg
  792. pop dx
  793. or ax,ax
  794. jnz got_it
  795. mov ds:[ne_swaparea],dx
  796. got_it:
  797. mov ax,ds:[ne_swaparea]
  798. mov dx,MxCodeSwapArea
  799. cmp cx,dx
  800. ja cant_get_that_much
  801. mov dx,cx
  802. cant_get_that_much:
  803. cEnd
  804. ;
  805. ; SetReserve - Sets gi_reserve to the given number of paragraphs
  806. ;
  807. ; Registers Destroyed:
  808. ; AX, BX, DX
  809. ;
  810. cProc SetReserve,<PUBLIC,FAR>,<di>
  811. parmW paras
  812. cBegin
  813. SetKernelDS
  814. mov ds, pGlobalHeap
  815. UnSetKernelDS
  816. xor di,di
  817. mov bx, paras
  818. mov ds:[di].gi_reserve, bx
  819. shl bx, 4
  820. cCall get_physical_address,<ds:[di].hi_last>
  821. sub ax, bx
  822. sbb dx, di
  823. mov ds:[di].gi_disfence_lo, ax
  824. mov ds:[di].gi_disfence_hi, dx
  825. cEnd
  826. sEnd CODE
  827. end