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.

1363 lines
56 KiB

  1. TITLE GMEM - Register interface to global memory allocator
  2. .xlist
  3. include kernel.inc
  4. include tdb.inc
  5. .list
  6. .386p
  7. include protect.inc
  8. DataBegin
  9. ;externW curTDB
  10. ;externW pGlobalHeap
  11. externW Win386_Blocks
  12. externW SelTableLen
  13. externD SelTableStart
  14. ifdef WOW
  15. globalB fInAlloc, 0
  16. globalW UserSelArray, 0
  17. globalW SelectorFreeBlock, 0
  18. endif
  19. if ROM
  20. externW gdtdsc
  21. endif
  22. DataEnd
  23. sBegin CODE
  24. assumes CS,CODE
  25. externNP DPMIProc
  26. ife ROM
  27. externW gdtdsc
  28. endif
  29. externNP gsplice
  30. externNP gjoin
  31. externNP gzero
  32. externNP gsearch
  33. externNP gmarkfree
  34. ;externNP gdel_free
  35. ;externNP gcheckfree
  36. externNP gmovebusy
  37. externNP gcompact
  38. externNP glruadd
  39. externNP glrudel
  40. externNP glrutop
  41. externNP gnotify
  42. externNP is_there_theoretically_enough_space
  43. externNP can_we_clear_this_space
  44. if ROM
  45. externNP IsROMObject
  46. endif
  47. externNP get_physical_address
  48. externNP alloc_sel
  49. externNP alloc_data_sel
  50. externFP IAllocCStoDSAlias
  51. externNP pdref
  52. externNP set_sel_limit
  53. externNP set_selector_limit32
  54. externNP set_selector_address32
  55. externNP mark_sel_PRESENT
  56. externNP mark_sel_NP
  57. externNP free_sel
  58. externNP FreeSelArray
  59. externNP GrowSelArray
  60. externNP get_arena_pointer32
  61. externNP get_temp_sel
  62. externNP AssociateSelector32
  63. externNP free_arena_header
  64. externNP PageLockLinear
  65. externNP UnlinkWin386Block
  66. externNP gwin386discard
  67. externNP PreAllocArena
  68. if KDEBUG
  69. externNP CheckGAllocBreak ; LINTERF.ASM
  70. endif
  71. ;-----------------------------------------------------------------------;
  72. ; galign ;
  73. ; ;
  74. ; Aligns the size request for a global item to a valid para boundary. ;
  75. ; ;
  76. ; Arguments: ;
  77. ; EBX = #bytes ;
  78. ; CF = 1 if #paras overflowed. ;
  79. ; ;
  80. ; Returns: ;
  81. ; EDX = #bytes aligned, to next higher multiple of 32 ;
  82. ; ;
  83. ; Error Returns: ;
  84. ; EDX = 0100000h ;
  85. ; ;
  86. ; Registers Preserved: ;
  87. ; all ;
  88. ; Registers Destroyed: ;
  89. ; none ;
  90. ; Calls: ;
  91. ; nothing ;
  92. ; History: ;
  93. ; ;
  94. ; Mon Sep 22, 1986 03:14:56p -by- David N. Weise [davidw] ;
  95. ; Added this nifty comment block. ;
  96. ;-----------------------------------------------------------------------;
  97. cProc galign,<PUBLIC,NEAR>
  98. cBegin nogen
  99. jc short align_error ; Overflow occur?
  100. lea edx,[ebx+GA_ALIGN_BYTES]; No, add alignment amount
  101. and dl,GA_MASK_BYTES ; ...modulo alignment boundary
  102. cmp edx,ebx ; Test for overflow
  103. jnb short align_exit ; OK, continue
  104. align_error:
  105. mov edx,0FF0000h ; Return largest possible size
  106. jmps align_exit1 ; 255*64k since max # selectors is 255
  107. align_exit:
  108. cmp edx, 100000h ; Greater than 1Mb?
  109. jbe short align_exit1 ; no, done
  110. add edx, 0FFFh ; yes, page align
  111. jc align_error
  112. and dx, not 0FFFh
  113. cmp edx, 0FF0000h ; Too big?
  114. ja short align_error ; yep, hard luck
  115. align_exit1:
  116. ret
  117. cEnd nogen
  118. ;-----------------------------------------------------------------------;
  119. ; galloc ;
  120. ; ;
  121. ; Allocates global memory. ;
  122. ; ;
  123. ; Arguments: ;
  124. ; AX = allocation flags ;
  125. ; BX = #paragraphs ;
  126. ; CX = owner field ;
  127. ; DS:DI = address of global heap info ;
  128. ; ;
  129. ; Returns: ;
  130. ; AX = handle to object or zero ;
  131. ; BX = size of largest free block if AX = 0 ;
  132. ; CX = AX ;
  133. ; ;
  134. ; Error Returns: ;
  135. ; DX = 0 ;
  136. ; ;
  137. ; Registers Preserved: ;
  138. ; ;
  139. ; Registers Destroyed: ;
  140. ; ;
  141. ; Calls: ;
  142. ; gsearch ;
  143. ; ghalloc ;
  144. ; glruadd ;
  145. ; gmarkfree ;
  146. ; History: ;
  147. ; ;
  148. ; Wed Jun 24, 1987 03:04:32a -by- David N. Weise [davidw] ;
  149. ; Added support for Global Notify. ;
  150. ; ;
  151. ; Mon Sep 22, 1986 02:38:19p -by- David N. Weise [davidw] ;
  152. ; Added this nifty comment block. ;
  153. ;-----------------------------------------------------------------------;
  154. AccessWord dw DSC_DATA+DSC_PRESENT
  155. dw (DSC_DISCARDABLE SHL 8) + DSC_DATA+DSC_PRESENT
  156. dw DSC_CODE+DSC_PRESENT
  157. dw (DSC_DISCARDABLE SHL 8) + DSC_CODE+DSC_PRESENT
  158. dw DSC_DATA+DSC_PRESENT
  159. dw (DSC_DISCARDABLE SHL 8) + DSC_DATA+DSC_PRESENT
  160. dw DSC_DATA+DSC_PRESENT
  161. dw (DSC_DISCARDABLE SHL 8) + DSC_DATA+DSC_PRESENT
  162. cProc galloc,<PUBLIC,NEAR>
  163. cBegin nogen
  164. if KDEBUG
  165. test al,GA_DISCCODE ; if discardable code, allow alloc
  166. jnz @F
  167. call CheckGAllocBreak
  168. jc gaerr ; time to fail...
  169. @@:
  170. endif
  171. cmp ebx, (16*1024*1020) ; Too big?
  172. ja gaerr ; yes.
  173. or ebx,ebx ; Allocating zero size?
  174. jz allocate_zero_size
  175. call gsearch ; Search for block big enough
  176. jz ga_exit ; Done, if couldn't get enough
  177. mov esi,eax
  178. push dx
  179. mov bx,dx
  180. mov edx, ds:[esi].pga_address
  181. mov ecx, ds:[esi].pga_size
  182. and bx, ((GA_CODE_DATA+GA_DISCARDABLE) shl 8) + GA_DGROUP
  183. or bl, bh
  184. xor bh, bh
  185. shl bx, 1
  186. mov ax, cs:AccessWord[bx] ; Pick up access rights for selector
  187. cCall alloc_sel,<edx,ecx>
  188. pop dx
  189. or ax, ax ; Did we get the selectors?
  190. jz short gaerr2 ; no, free block and return
  191. add ecx, 0FFFFh ; Calculate # selectors we got
  192. shr ecx, 16
  193. mov ds:[esi].pga_selcount, cl
  194. cCall AssociateSelector32,<ax,esi>
  195. test dl,GA_MOVEABLE ; Is this a moveable object?
  196. jnz short moveable
  197. test dh, GA_DISCARDABLE ; We have a fixed block
  198. jnz short not_moveable ; Not interested in discardable blocks
  199. mov bx, ax
  200. ifdef WOW
  201. ; the following dpmicall is basically a NOP. so just
  202. ; avoid the call altogether.
  203. ; - Nanduri Ramakrishna
  204. else
  205. DPMICALL 0004H
  206. jc short gaerr1
  207. endif
  208. inc [esi].pga_pglock ; Mark it locked
  209. mov ax, bx
  210. jmps not_moveable
  211. moveable:
  212. mov ds:[esi].pga_count,0 ; Initialize lock count to 0
  213. StoH ax ; Mark as moveable block
  214. not_moveable:
  215. mov ds:[esi].pga_handle,ax ; Set handle in arena
  216. mov bx, ax ; AX and BX handle
  217. call glruadd ; Yes, Add to LRU chain
  218. mov cx,ax
  219. ret
  220. allocate_zero_size:
  221. test al,GA_MOVEABLE ; Yes, moveable?
  222. jz short gaerr ; No, return error (AX = 0)
  223. mov bx, ax
  224. and bx, ((GA_CODE_DATA+GA_DISCARDABLE) shl 8) + GA_DGROUP
  225. or bl, bh ; Above bits are exclusive
  226. xor bh, bh
  227. shl bx, 1
  228. mov ax, cs:AccessWord[bx] ; Pick up access rights for selector
  229. and al, NOT DSC_PRESENT ; These are NOT present
  230. xor edx, edx ; Base of zero for now
  231. cCall alloc_sel,<edx,dx,cx>
  232. or ax, ax
  233. jz short gaerr
  234. cCall AssociateSelector32,<ax,0,cx> ; Save owner in selector table
  235. StoH al ; Handles are RING 2
  236. mov bx,ax
  237. ga_exit:
  238. mov cx,ax
  239. ret
  240. gaerr1: ; Failed to page lock, free up everthing
  241. cCall FreeSelArray,<bx>
  242. gaerr2: ; Failed to get selectors
  243. xor edx,edx
  244. call gmarkfree
  245. gaerr:
  246. KernelLogError DBF_WARNING,ERR_GALLOC,"GlobalAlloc failed"
  247. xor dx,dx ; DX = 0 means NOT out of memory
  248. xor ax,ax ; Return AX = 0 to indicate error
  249. jmps ga_exit
  250. cEnd nogen
  251. ;-----------------------------------------------------------------------;
  252. ; grealloc ;
  253. ; ;
  254. ; Reallocates the given global memory object. ;
  255. ; ;
  256. ; Arguments: ;
  257. ; AX = allocation flags ;
  258. ; EBX = #bytes for new size ;
  259. ; CX = new owner field value ;
  260. ; DX = existing handle ;
  261. ; DS:DI = address of global heap info ;
  262. ; ;
  263. ; Returns: ;
  264. ; AX = handle to object or zero ;
  265. ; DX = size of largest free block if AX = 0 ;
  266. ; CX = AX ;
  267. ; ;
  268. ; Registers Preserved: ;
  269. ; ;
  270. ; Registers Destroyed: ;
  271. ; SI ;
  272. ; ;
  273. ; Calls: ;
  274. ; ;
  275. ; History: ;
  276. ; ;
  277. ; Mon Sep 22, 1986 10:11:48a -by- David N. Weise [davidw] ;
  278. ; Added this nifty comment block. ;
  279. ;-----------------------------------------------------------------------;
  280. cProc grealloc,<PUBLIC,NEAR>
  281. cBegin nogen
  282. push bp
  283. mov bp,sp
  284. push ax
  285. rflags EQU word ptr [bp-2]
  286. push dx
  287. h EQU word ptr [bp-4]
  288. push cx
  289. owner EQU word ptr [bp-6]
  290. push ebx
  291. rsize EQU dword ptr [bp-10]
  292. sub sp, 6
  293. canmove EQU byte ptr [bp-12]
  294. locked EQU byte ptr [bp-13]
  295. mflags EQU byte ptr [bp-14]
  296. pgLockSel EQU word ptr [bp-16]
  297. push dx
  298. oldh EQU word ptr [bp-18]
  299. mov pgLockSel, 0 ; No selector to free yet
  300. call pdref
  301. mov dx, bx ; save owner if discarded
  302. mov word ptr (mflags), cx
  303. mov ebx,rsize
  304. jz racreate ; Do nothing with 0, free or discarded handles
  305. handle_ok:
  306. test byte ptr rflags,GA_MODIFY ; Want to modify table flags?
  307. jnz short ramodify ; Yes go do it
  308. or ebx,ebx ; Are we reallocing to zero length?
  309. jz short to_0
  310. jmp raokay ; No, continue
  311. to_0: or ch,ch ; Is handle locked?
  312. jz short radiscard
  313. rafail:
  314. KernelLogError DBF_WARNING,ERR_GREALLOC,"GlobalReAlloc failed"
  315. xor ax,ax ; Yes, return failure
  316. xor dx,dx
  317. jmp raexit
  318. radiscard: ; No, then try to discard the object
  319. ; Here to discard object, when reallocating to zero size. This
  320. ; feature is only enabled if the caller passes the moveable flag
  321. test byte ptr rflags,GA_MOVEABLE ; Did they want to discard?
  322. jz short rafail ; No, then return failure.
  323. mov al,GN_DISCARD ; AL = discard message code
  324. xor cx,cx ; CX = means realloc
  325. mov bx, ds:[esi].pga_handle ; BX = handle
  326. push es
  327. call gnotify ; See if okay to discard
  328. pop es
  329. jz short rafail ; No, do nothing
  330. call glrudel ; Yes, Delete handle from LRU chain
  331. cCall mark_sel_NP,<ds:[esi].pga_handle,ds:[esi].pga_owner>
  332. xor edx,edx
  333. call gmarkfree ; Free client data
  334. jz short rafixed ; Return NULL if freed a fixed block
  335. jmp rasame ; Return original handle, except
  336. ; GlobalLock will now return null.
  337. rafixed:
  338. xor ax,ax
  339. jmp raexit
  340. ramodify:
  341. if ROM
  342. cCall IsROMObject, <h>
  343. or ax, ax
  344. jnz rasame1
  345. endif
  346. mov ax,rflags ; Get new flags
  347. mov dx,owner ; Get new owner field value
  348. mov bx, ds:[esi].pga_handle
  349. test bl, GA_FIXED ; Moveable object?
  350. jz short is_moveable
  351. test al,GA_MOVEABLE ; Make fixed into moveable?
  352. jz short ramod2 ; No, change owner only
  353. StoH bx ; Turn selector into handle
  354. mov ds:[esi].pga_handle, bx
  355. mov ds:[esi].pga_count, 0 ; 0 lock count for new movable obj
  356. is_moveable:
  357. call glrudel ; Yes, remove from lru chain
  358. push ax
  359. push ecx
  360. lar ecx, ebx ; Get existing access rights
  361. shr ecx, 8
  362. test ah, GA_DISCARDABLE ; Do we want it to be discardable?
  363. jnz short ra_want_discardable
  364. .errnz DSC_DISCARDABLE-10h
  365. btr cx, 12 ; Ensure DSC_DISCARDABLE is off
  366. jnc short ra_ok_disc_bit ; it was
  367. jmps ra_set_access ; nope, must reset it
  368. ra_want_discardable:
  369. bts cx, 12 ; Ensure DSC_DISCARDABLE is on
  370. jc short ra_ok_disc_bit
  371. ra_set_access:
  372. DPMICALL 0009h
  373. ra_ok_disc_bit:
  374. pop ecx
  375. pop ax
  376. ra_notdiscardable:
  377. test cl,HE_DISCARDED ; Is this a discarded handle?
  378. jz short ramod1 ; No, continue
  379. test ah,GA_SHAREABLE ; Only change owner if making shared
  380. jz short rasame1
  381. int 3
  382. push ax
  383. push ecx
  384. lsl ecx, ebx ; Use existing high limit bits
  385. shr ecx, 16
  386. DPMICALL 0008h ; Set segment limit (to CX:DX)
  387. pop ecx
  388. pop ax
  389. jmps rasame1
  390. ramod1:
  391. call glruadd ; Add to lru chain if now discardable
  392. ramod2:
  393. test ah,GA_SHAREABLE ; Only change owner if making shared
  394. jz short rasame1
  395. mov ds:[esi].pga_owner,dx ; Set new owner value
  396. rasame1:
  397. jmp rasame
  398. rafail0:
  399. jmp rafail
  400. racreate:
  401. test cl,HE_DISCARDED ; Is this a discarded handle?
  402. jz short rafail0 ; No, return error
  403. or ebx,ebx ; Are we reallocing to zero length?
  404. jz short rasame1 ; Yes, return handle as is.
  405. if KDEBUG
  406. test cl,GA_DISCCODE ; if discardable code, allow realloc
  407. jnz @F
  408. call CheckGAllocBreak
  409. jc rafail0
  410. @@:
  411. endif
  412. mov ax,GA_MOVEABLE ; Reallocating a moveable object
  413. or ax,rflags ; ...plus any flags from the caller
  414. ; DO NOT CHANGE: flag conflict
  415. ; GA_DISCARDABLE == GA_ALLOCHIGH.
  416. and cl,not (HE_DISCARDED + GA_ALLOCHIGH)
  417. or al,cl
  418. mov cx,dx ; get owner
  419. test al,GA_DISCCODE ; Discardable code segment?
  420. jz short ranotcode
  421. or al,GA_ALLOCHIGH ; Yes, allocate high
  422. ranotcode:
  423. or al, COMPACT_ALLOC ; Allow discarding
  424. mov [di].gi_cmpflags,al ; Save flags for gcompact
  425. and [di].gi_cmpflags,CMP_FLAGS or GA_ALLOCHIGH
  426. push si ; save handle
  427. call gsearch ; Find block big enough
  428. pop si ; restore existing handle
  429. jz rafailmem1
  430. cCall mark_sel_PRESENT,<eax,si>
  431. or si,si ; Might have failed to grow selector array
  432. jz short racre_worst_case
  433. xchg eax,esi ; Return original handle
  434. ; Set back link to handle in new block
  435. cCall AssociateSelector32,<ax,esi>
  436. mov ds:[esi].pga_handle,ax
  437. mov ds:[esi].pga_count,0
  438. ; and ch,GA_SEGTYPE ; OPTIMIZE superfluous??
  439. ; and es:[di].ga_flags,GAH_NOTIFY
  440. ; or es:[di].ga_flags,ch ; Copy segment type flags to ga_flags
  441. call glruadd ; Add to LRU chain
  442. jmp raexit
  443. racre_worst_case:
  444. mov esi, eax ; Free block if selectors not available
  445. xor edx, edx
  446. call gmarkfree
  447. KernelLogError DBF_WARNING,ERR_GREALLOC,"GlobalReAlloc failed"
  448. xor dx, dx
  449. xor ax, ax
  450. jmp raexit
  451. raokay:
  452. if KDEBUG
  453. test ds:[esi].pga_flags,GA_DISCCODE
  454. jz short ok
  455. Debug_Out "GlobalReAlloc of Discardable Code"
  456. ok:
  457. endif
  458. cmp ebx,ds:[esi].pga_size
  459. jz short rasame
  460. clc
  461. call galign ; assuming there is room.
  462. ; Here if not trying to realloc this block to zero
  463. ; FS:ESI = arena header of current block
  464. ; AX:0 = client address of current block
  465. ; CH = lock count of current block
  466. ; EDX = new requested size
  467. cmp ds:[esi].pga_pglock, 0 ; Are we page locked?
  468. je short ranolock
  469. push ax
  470. push dx
  471. push es
  472. cCall IAllocCStoDSAlias,<h> ; Get an alias selector (type doesn't
  473. pop es
  474. pop dx
  475. mov pgLockSel, ax ; matter)
  476. or ax, ax ; Got selector?
  477. pop ax
  478. jz rafail ; no, goodbye
  479. ranolock:
  480. mov ebx,ds:[esi].pga_next ; Get address of current next header
  481. cmp edx,ds:[esi].pga_size ; Are we growing or shrinking?
  482. ja short raextend ; We are growing
  483. call rashrink
  484. ifdef WOW
  485. ; the following dpmicall is basically a NOP. so just
  486. ; avoid the call altogether.
  487. ; - Nanduri Ramakrishna
  488. else
  489. mov bx, h
  490. mov ax, pgLockSel ; Were we page locked?
  491. or ax, ax
  492. jz short rasame ; no, nothing to do
  493. Handle_To_Sel bl
  494. DPMICALL 0004h
  495. endif
  496. rasame_pglock:
  497. ifdef WOW
  498. ; avoid the call altogether.
  499. else
  500. mov bx, pgLockSel ; Were we page locked?
  501. or bx, bx
  502. jz short rasame
  503. DPMICALL 0005h
  504. endif
  505. rasame:
  506. mov ax,h ; Return the same handle
  507. jmp raexit ; All done
  508. raextend:
  509. test rflags,GA_DISCCODE ; Not allowed to grow a disccode seg
  510. jnz short rafail1
  511. if KDEBUG
  512. call CheckGAllocBreak
  513. jc rafail1
  514. endif
  515. push ax
  516. call GrowSelArray
  517. mov cx, ax
  518. pop ax ; Did we get the selectors?
  519. jcxz rafail1 ; no, fail
  520. mov h, cx ; Update handle
  521. call ragrow
  522. jnc short rasame_pglock ; Success
  523. test mflags,GA_DISCARDABLE ; if discardable, just stop now
  524. jz short ramove ; since it might get discarded!
  525. rafail1:
  526. jmp rafail
  527. ; Here to try to move the current block
  528. ; AX = client address of current block
  529. ; ES:0 = arena header of current block
  530. ; CH = lock count of current block
  531. ; EDX = new requested size of block
  532. ramove:
  533. mov ebx, edx ; Size now in EBX
  534. mov canmove, 1
  535. mov dx,rflags ; get the passed in flags
  536. test dx,GA_MOVEABLE ; Did they say OK to move
  537. jnz short ramove1 ; Yes, try to move even iflocked or fixed
  538. cmp locked, 0 ; Locked?
  539. ; Continue if this handle not locked
  540. jnz short racompact ; yes, try to find space to grow in place
  541. or dx,GA_MOVEABLE ; If moveable, make sure bit set.
  542. test h,GA_FIXED ; Is this a moveable handle?
  543. jz short ramove2 ; Yes, okay to move
  544. racompact:
  545. xor dx,dx ; No, get size of largest free block
  546. call gcompact
  547. jmp racantmove
  548. ramove1:
  549. test h, GA_FIXED
  550. jz short ramove2
  551. and dx, NOT GA_MOVEABLE
  552. ramove2:
  553. mov ax,dx ; AX = allocation flags
  554. ;;; mov bx,si ; EBX = size of new block
  555. mov cx,1 ; CX = owner (use size for now)
  556. call gsearch ; Find block big enough
  557. jz short racantmove ; Cant find one, grow in place now?
  558. mov esi, eax ; ESI = destination arena
  559. call PreAllocArena ; Required for gmovebusy
  560. jz short ramove2a
  561. mov cx, pgLockSel ; Do we have to page lock it?
  562. jcxz ramove3
  563. cCall PageLockLinear,<ds:[esi].pga_address,ds:[esi].pga_size>
  564. jnc short ramove3 ; Locked it?
  565. ramove2a:
  566. xor edx, edx ; no, free memory block
  567. call gmarkfree
  568. jmps racantmove
  569. ramove3:
  570. mov cx,h
  571. cCall get_arena_pointer32,<cx>
  572. mov edx,eax
  573. call gmovebusy ; Call common code to move busy block
  574. ; (AX destroyed)
  575. push ebx
  576. push esi
  577. mov esi, edx ; free block just emptied
  578. mov ebx, ds:[esi].pga_prev ; See if block can be
  579. cmp ds:[ebx].pga_owner, GA_NOT_THERE; returned to win386
  580. jne short ra_no_unlink
  581. push ecx
  582. mov ecx, ds:[esi].pga_next
  583. cmp ds:[ecx].pga_owner, GA_NOT_THERE
  584. jne short ra_no_unlink_ecx
  585. mov eax, ds:[ecx].pga_next
  586. cmp eax, ds:[eax].pga_next ; Sentinel?
  587. je short ra_no_unlink_ecx ; yes, keep this block
  588. push edx
  589. push edi
  590. cCall UnlinkWin386Block
  591. pop edi
  592. pop edx
  593. ra_no_unlink_ecx:
  594. pop ecx
  595. ra_no_unlink:
  596. pop esi
  597. pop ebx
  598. cCall set_selector_limit32,<ds:[esi].pga_handle,ds:[esi].pga_size>
  599. jmp rasame_pglock
  600. racantmove:
  601. mov dx, h
  602. call pdref
  603. mov ebx,rsize
  604. clc
  605. call galign ; assuming there is room.
  606. mov ebx,ds:[esi].pga_next ; Get address of current next header
  607. call ragrow
  608. jc short racmove3
  609. jmp rasame_pglock
  610. racmove3:
  611. xor dx,dx ; No, get size of largest free block
  612. call gcompact
  613. mov dx,ax ; DX = size of largest free block
  614. rafailmem:
  615. mov eax,ds:[esi].pga_size ; AX = size of current block
  616. mov esi,ds:[esi].pga_next ; Check following block
  617. cmp ds:[esi].pga_owner,di ; Is it free?
  618. jne short rafailmem0 ; No, continue
  619. add eax,ds:[esi].pga_size ; Yes, then include it as well
  620. ;;; inc ax
  621. rafailmem0:
  622. cmp ax,dx ; Choose the larger of the two
  623. jbe short rafailmem1
  624. mov dx,ax
  625. rafailmem1:
  626. push dx ; Save DX
  627. KernelLogError DBF_WARNING,ERR_GREALLOC,"GlobalReAlloc failed"
  628. pop dx ; Restore DX
  629. xor ax,ax
  630. raexit:
  631. push ax
  632. push bx
  633. push dx
  634. mov bx, pgLockSel
  635. or bx, bx ; Have alias selector?
  636. jz short noSel ; nope, all ok
  637. cCall free_sel,<bx>
  638. noSel:
  639. mov bx, h
  640. ;;; inc bl
  641. and bl, NOT 1
  642. mov cx, oldh
  643. ;;; inc cl
  644. and cl, NOT 1
  645. cmp bx, cx ; Did we get new selector array?
  646. je short no_new_handle ; nope.
  647. or ax, ax ; Did we succeed?
  648. jz short free_new
  649. HtoS cl
  650. cCall FreeSelArray,<cx> ; Free old selector array
  651. jmps no_new_handle
  652. ; Update old selector array
  653. free_new:
  654. HtoS bl
  655. cCall get_arena_pointer32,<bx> ; Get new arena (may have moved)
  656. mov esi,eax
  657. HtoS cl
  658. cCall AssociateSelector32,<cx,esi> ; Set up old sel array
  659. cCall set_selector_address32,<cx,ds:[esi].pga_address>
  660. lsl ecx, ecx ; Get old length
  661. if KDEBUG
  662. jz short @F
  663. int 3
  664. @@:
  665. endif
  666. add ecx, 10000h
  667. shr ecx, 16 ; CL has old # selectors
  668. xchg ds:[esi].pga_selcount, cl
  669. mov ax, oldh
  670. xchg ds:[esi].pga_handle, ax ; Reset handle
  671. cCall AssociateSelector32,<ax,0,0> ; Disassociate new array
  672. fsloop:
  673. cCall free_sel,<ax> ; Free new selector array
  674. add ax, 8
  675. loop fsloop
  676. no_new_handle:
  677. pop dx
  678. pop bx
  679. pop ax
  680. mov cx, ax
  681. mov sp,bp
  682. pop bp
  683. ret
  684. cEnd nogen
  685. ;-----------------------------------------------------------------------;
  686. ; rashrink ;
  687. ; ;
  688. ; Shrinks the given block ;
  689. ; ;
  690. ; Arguments: ;
  691. ; Here to shrink a block ;
  692. ; DS:ESI = arena header of current block ;
  693. ; DS:EBX = arena header of next block ;
  694. ; EDX = new requested size ;
  695. ; ;
  696. ; Returns: ;
  697. ; ;
  698. ; Registers Preserved: ;
  699. ; ;
  700. ; Registers Destroyed: ;
  701. ; ALL but DS, DI ;
  702. ; ;
  703. ; Calls: ;
  704. ; gsplice ;
  705. ; gmarkfree ;
  706. ; ;
  707. ; History: ;
  708. ; ;
  709. ;-----------------------------------------------------------------------;
  710. cProc rashrink,<PUBLIC,NEAR>
  711. cBegin nogen
  712. call PreAllocArena ; Make sure we can do it
  713. jz short rashrunk
  714. mov ax,ds:[esi].pga_handle
  715. or ax,ax
  716. jz short ra_free
  717. Handle_To_Sel al
  718. push ecx
  719. push edx
  720. lsl ecx, eax
  721. Limit_To_Selectors ecx ; Old # selectors
  722. dec edx
  723. Limit_To_Selectors edx ; New # selectors
  724. sub cx, dx
  725. jbe short none_to_free
  726. mov ds:[esi].pga_selcount, dl
  727. push ax
  728. .errnz SIZE DscPtr-8
  729. shl dx, 3
  730. add ax, dx ; First selector to free
  731. ras_loop:
  732. cCall free_sel,<ax>
  733. add ax, SIZE DscPtr
  734. loop ras_loop
  735. pop ax
  736. none_to_free:
  737. pop edx
  738. pop ecx
  739. cCall set_selector_limit32,<ax,edx>
  740. ra_free:
  741. cmp edx,ds:[esi].pga_size ; Enough room from for free block?
  742. jae short rashrunk ; No, then no change to make
  743. call gsplice ; splice new block into the arena
  744. mov esi, edx
  745. xor edx, edx
  746. call gmarkfree ; Mark it as free
  747. rashrunk:
  748. ret
  749. cEnd nogen
  750. ;-----------------------------------------------------------------------;
  751. ; ragrow ;
  752. ; ;
  753. ; Tries to grow the given global memory object in place ;
  754. ; ;
  755. ; Arguments: ;
  756. ; AX:0 = client address of current block ;
  757. ; FS:ESI = arena header of current block ;
  758. ; FS:EBX = arena header of next block ;
  759. ; EDX = new requested size of block ;
  760. ; ;
  761. ; Returns: ;
  762. ; CY = 0 Success ;
  763. ; ;
  764. ; CY = 1 Failed ;
  765. ; ESI preserved ;
  766. ; EDX contains free memory required ;
  767. ; ;
  768. ; ;
  769. ; Registers Preserved: ;
  770. ; ;
  771. ; Registers Destroyed: ;
  772. ; ALL but DS, DI ;
  773. ; ;
  774. ; Calls: ;
  775. ; is_there_theoretically_enough_space ;
  776. ; can_we_clear_this_space ;
  777. ; gjoin ;
  778. ; gzero ;
  779. ; rashrink ;
  780. ; ;
  781. ; History: ;
  782. ; ;
  783. ; Mon 05-Sep-1988 20:10:15 -by- David N. Weise [davidw] ;
  784. ; Made ragrow be more intelligent by trying to extend into moveable ;
  785. ; blocks. ;
  786. ;-----------------------------------------------------------------------;
  787. cProc ragrow,<PUBLIC,NEAR>
  788. cBegin nogen
  789. push ds:[esi].pga_size ; Save in case we have to back out
  790. push edx
  791. push esi ; Save current block address
  792. sub edx, ds:[esi].pga_size ; compute amount of free space wanted
  793. xchg esi,ebx ; ESI = next block address
  794. mov cx,[di].hi_count
  795. push ax
  796. push cx
  797. push esi
  798. call is_there_theoretically_enough_space
  799. pop esi
  800. pop cx
  801. cmp eax,edx
  802. jb short ragx
  803. call can_we_clear_this_space
  804. jz short ragx
  805. cCall alloc_data_sel,<ds:[esi].pga_address, edx>
  806. or ax, ax ; Did we get a selector?
  807. jnz short okk ; yes, continue
  808. jmps ragx
  809. okk:
  810. mov cx, ax
  811. pop ax
  812. push cx ; Parameter to free_sel (below)
  813. push edx
  814. call gjoin ; and attach to end of current block
  815. pop edx
  816. test byte ptr rflags,GA_ZEROINIT ; Zero fill extension?
  817. jz short ranz ; No, continue
  818. mov bx,cx ; Yes, BX = first paragraph to fill
  819. mov ecx,edx ; compute last paragraph to fill
  820. call gzero ; zero fill extension
  821. ranz:
  822. call FreeSelArray
  823. pop edx ; clear the stack
  824. pop edx ; New length of block
  825. mov bx, ds:[esi].pga_handle
  826. Handle_To_Sel bl
  827. cCall set_selector_limit32,<bx,edx>
  828. ifndef WOW ; WOW doesn't lock pages
  829. cmp ds:[esi].pga_pglock, 0
  830. je short rag1
  831. mov ax, 4 ; Page lock the whole thing
  832. int 31h
  833. mov ax, bx
  834. jc short rag2
  835. endif; WOW
  836. rag1:
  837. mov ebx,ds:[esi].pga_next ; Pick up new next block address
  838. call rashrink ; Now shrink block to correct size
  839. add sp, 4
  840. clc
  841. ret
  842. ragx:
  843. pop ax
  844. pop esi ; Recover current block address
  845. pop edx
  846. add sp, 4 ; toss original size
  847. stc
  848. ret
  849. rag2:
  850. if KDEBUG
  851. int 3
  852. endif
  853. pop edx ; Shrink back to orignal size
  854. mov ebx, ds:[esi].pga_next
  855. call rashrink
  856. stc ; and fail
  857. ret
  858. cEnd nogen
  859. ;-----------------------------------------------------------------------;
  860. ; gfree ;
  861. ; ;
  862. ; Frees a global object. ;
  863. ; ;
  864. ; Arguments: ;
  865. ; DX = global memory object handle ;
  866. ; CX = owner field value to match or zero if dont care ;
  867. ; DS:DI = address of global heap info ;
  868. ; ;
  869. ; Returns: ;
  870. ; AX = 0 ;
  871. ; CX = 0 ;
  872. ; ;
  873. ; Error Returns: ;
  874. ; AX = -1 ;
  875. ; CX = -1 ;
  876. ; ;
  877. ; Registers Preserved: ;
  878. ; ;
  879. ; Registers Destroyed: ;
  880. ; ? ;
  881. ; Calls: ;
  882. ; gdref ;
  883. ; free_object ;
  884. ; hfree ;
  885. ; ;
  886. ; History: ;
  887. ; ;
  888. ; Sat Sep 20, 1986 11:48:38a -by- David N. Weise [davidw] ;
  889. ; Added this nifty comment block and restructured. ;
  890. ;-----------------------------------------------------------------------;
  891. cProc gfree,<PUBLIC,NEAR>
  892. cBegin nogen
  893. push cx
  894. call pdref
  895. pop dx
  896. jz short object_discarded
  897. call free_object
  898. jmps gfree_exit
  899. ;** When the object is discarded, we have to remove the sel table
  900. ;* pointer to the object (this points to the >owner< of the
  901. ;** block for discardable objects)
  902. object_discarded:
  903. PUBLIC object_discarded
  904. xor eax,eax
  905. cCall AssociateSelector32, <si,eax> ;Remove in the sel table
  906. cCall FreeSelArray,<si>
  907. xor ax,ax ;Force success
  908. gfree_exit:
  909. mov cx,ax
  910. ret
  911. cEnd nogen
  912. ;-----------------------------------------------------------------------;
  913. ; free_object ;
  914. ; ;
  915. ; Arguments: ;
  916. ; DX = owner field value to match or zero if dont care ;
  917. ; DS:DI = address of global heap info ;
  918. ; ES:ESI = address of arena header ;
  919. ; ;
  920. ; Returns: ;
  921. ; AX = 0 ;
  922. ; ;
  923. ; Error Returns: ;
  924. ; AX = -1 ;
  925. ; ;
  926. ; Registers Preserved: ;
  927. ; ;
  928. ; Registers Destroyed: ;
  929. ; ;
  930. ; Calls: ;
  931. ; glrudel ;
  932. ; gmarkfree ;
  933. ; hfree ;
  934. ; History: ;
  935. ; ;
  936. ; Sat Sep 20, 1986 02:59:06p -by- David N. Weise [davidw] ;
  937. ; Moved it from gfree. ;
  938. ;-----------------------------------------------------------------------;
  939. cProc free_object,<PUBLIC,NEAR>
  940. cBegin nogen
  941. or dx,dx
  942. jz short free_it
  943. cmp ds:[esi].pga_owner,dx
  944. je short free_it
  945. mov ax,-1
  946. jmps free_object_exit
  947. free_it:
  948. call glrudel ; delete object from LRU chain
  949. ifdef WOW
  950. ; No need to call DPMI to unpagelock
  951. else
  952. movzx cx, ds:[esi].pga_pglock
  953. jcxz fo_notpglocked
  954. mov bx, ds:[esi].pga_handle
  955. unpagelock:
  956. DPMICALL 0005h
  957. loop unpagelock
  958. endif
  959. mov ds:[esi].pga_pglock, 0
  960. fo_notpglocked:
  961. push dx
  962. xor edx,edx
  963. call gmarkfree ; free the object
  964. mov ebx, ds:[esi].pga_prev ; See if block can be
  965. cmp ds:[ebx].pga_owner, GA_NOT_THERE; returned to win386
  966. jne short fo_no_return
  967. mov ecx, ds:[esi].pga_next
  968. cmp ds:[ecx].pga_owner, GA_NOT_THERE
  969. jne short fo_no_return
  970. push ecx
  971. mov ecx, ds:[ecx].pga_next
  972. cmp ecx, ds:[ecx].pga_next ; Sentinel?
  973. pop ecx
  974. je short fo_no_return ; yes, keep this block
  975. cCall UnlinkWin386Block
  976. jmps fo_no_discard
  977. fo_no_return:
  978. call gwin386discard
  979. fo_no_discard:
  980. Handle_To_Sel dl
  981. cCall AssociateSelector32,<dx,edi> ; Trash sel table entry
  982. cCall FreeSelArray,<dx>
  983. pop dx
  984. xor ax,ax ;!!! just for now force success
  985. free_object_exit:
  986. ret
  987. cEnd nogen
  988. cProc free_object2,<PUBLIC,FAR>
  989. cBegin nogen
  990. call glrudel ; delete object from LRU chain
  991. ifdef WOW
  992. ; No need to call DPMI to unpagelock
  993. else
  994. movzx cx, ds:[esi].pga_pglock
  995. jcxz fo2_notpglocked
  996. mov bx, ds:[esi].pga_handle
  997. unpagelock2:
  998. DPMICALL 0005h
  999. loop unpagelock2
  1000. endif
  1001. mov ds:[esi].pga_pglock, 0
  1002. fo2_notpglocked:
  1003. xor edx,edx
  1004. call gmarkfree ; free the object
  1005. mov ebx, ds:[esi].pga_prev ; See if block can be
  1006. cmp ds:[ebx].pga_owner, GA_NOT_THERE; returned to win386
  1007. jne short fo2_no_return
  1008. mov ecx, ds:[esi].pga_next
  1009. cmp ds:[ecx].pga_owner, GA_NOT_THERE
  1010. jne short fo2_no_return
  1011. push ecx
  1012. mov ecx, ds:[ecx].pga_next
  1013. cmp ecx, ds:[ecx].pga_next ; Sentinel?
  1014. pop ecx
  1015. je short fo2_no_return ; yes, keep this block
  1016. cCall UnlinkWin386Block
  1017. jmps fo2_no_discard
  1018. fo2_no_return:
  1019. call gwin386discard
  1020. fo2_no_discard:
  1021. xor ax,ax ;!!! just for now force success
  1022. ret
  1023. cEnd nogen
  1024. ;-----------------------------------------------------------------------;
  1025. ; free_handle ;
  1026. ; ;
  1027. ; Frees the given handle. ;
  1028. ; ;
  1029. ; Arguments: ;
  1030. ; DS:SI = handle table entry address ;
  1031. ; ;
  1032. ; Returns: ;
  1033. ; AX = 0 ;
  1034. ; CX = AX ;
  1035. ; ;
  1036. ; Error Returns: ;
  1037. ; AX = -1 ;
  1038. ; ;
  1039. ; Registers Preserved: ;
  1040. ; BX ;
  1041. ; ;
  1042. ; Registers Destroyed: ;
  1043. ; ? ;
  1044. ; Calls: ;
  1045. ; hfree ;
  1046. ; History: ;
  1047. ; ;
  1048. ; Sat Sep 20, 1986 02:30:32p -by- David N. Weise [davidw] ;
  1049. ; Moved it from gfree. ;
  1050. ;-----------------------------------------------------------------------;
  1051. ;cProc free_handle,<PUBLIC,NEAR>
  1052. ;cBegin nogen
  1053. ; xor ax,ax
  1054. ; or si,si
  1055. ; jz short free_handle_exit
  1056. ; push bx
  1057. ; mov bx,si
  1058. ; call hfree
  1059. ; pop bx
  1060. ;free_handle_exit:
  1061. ; ret
  1062. ;cEnd nogen
  1063. ;-----------------------------------------------------------------------;
  1064. ; gfreeall ;
  1065. ; ;
  1066. ; Frees all global objects that belong to the given owner. It first ;
  1067. ; loops through the global heap freeing objects and then loops through ;
  1068. ; the handle table freeing handles of discarded objects. ;
  1069. ; ;
  1070. ; Arguments: ;
  1071. ; DX = owner field value to match ;
  1072. ; DS:DI = address of global heap info ;
  1073. ; ;
  1074. ; Returns: ;
  1075. ; ;
  1076. ; Registers Preserved: ;
  1077. ; ;
  1078. ; Registers Destroyed: ;
  1079. ; CX,ES,SI ;
  1080. ; ;
  1081. ; Calls: ;
  1082. ; free_object ;
  1083. ; henum ;
  1084. ; hfree ;
  1085. ; ;
  1086. ; History: ;
  1087. ; ;
  1088. ; Fri Sep 19, 1986 05:46:52p -by- David N. Weise [davidw] ;
  1089. ; Added this nifty comment block. ;
  1090. ;-----------------------------------------------------------------------;
  1091. cProc gfreeall,<PUBLIC,NEAR>
  1092. cBegin nogen
  1093. mov esi,[di].phi_first ; ES:DI points to first arena entry
  1094. mov cx,[di].hi_count ; CX = #entries in the arena
  1095. free_all_objects:
  1096. push cx
  1097. call free_object ; Free object if matches owner
  1098. pop cx
  1099. mov esi,ds:[esi].pga_next ; Move to next block
  1100. loop free_all_objects
  1101. ; may go extra times, as CX does not track coalescing done by gfree,
  1102. ; but no big whoop
  1103. push ax
  1104. push ebx
  1105. push edi
  1106. CheckKernelDS FS
  1107. ReSetKernelDS FS
  1108. movzx ecx, SelTableLen
  1109. shr ecx, 2
  1110. mov edi, SelTableStart
  1111. mov esi, edi
  1112. smov es, ds
  1113. UnSetKernelDS FS
  1114. free_all_handles_loop:
  1115. movzx eax, dx
  1116. repne scas dword ptr es:[edi] ; Isn't this easy?
  1117. jne short we_be_done
  1118. lea eax, [edi-4]
  1119. sub eax, esi
  1120. shl ax, 1
  1121. or al, SEG_RING
  1122. lar ebx, eax
  1123. test bh,DSC_PRESENT ; segment present?
  1124. jnz short free_all_handles_loop ; yes, not a handle
  1125. test ebx,DSC_DISCARDABLE SHL 16 ; discardable?
  1126. jz short free_all_handles_loop ; no, nothing to free
  1127. cCall FreeSelArray,<ax>
  1128. mov dword ptr [edi-4], 0 ; Remove owner from table
  1129. jmps free_all_handles_loop
  1130. we_be_done:
  1131. pop edi
  1132. pop ebx
  1133. pop ax
  1134. gfreeall_done:
  1135. ret
  1136. cEnd nogen
  1137. ;-----------------------------------------------------------------------;
  1138. ; glock ;
  1139. ; ;
  1140. ; Increment the lock count of an object in handle table entry ;
  1141. ; ;
  1142. ; Arguments: ;
  1143. ; BX = handle to global object ;
  1144. ; CH = handle table flags ;
  1145. ; CL = lock count for moveable objects ;
  1146. ; DX = segment address of object ;
  1147. ; DS:DI = address of master object ;
  1148. ; ES:DI = arena header ;
  1149. ; ;
  1150. ; Returns: ;
  1151. ; CX = updated lock count ;
  1152. ; DX = pointer to client area ;
  1153. ; ;
  1154. ; Error Returns: ;
  1155. ; ZF = 1 if count overflowed. ;
  1156. ; ;
  1157. ; Registers Preserved: ;
  1158. ; AX ;
  1159. ; ;
  1160. ; Registers Destroyed: ;
  1161. ; ;
  1162. ; Calls: ;
  1163. ; nothing ;
  1164. ; History: ;
  1165. ; ;
  1166. ; Fri Sep 19, 1986 05:38:57p -by- David N. Weise [davidw] ;
  1167. ; Added this nifty comment block. ;
  1168. ;-----------------------------------------------------------------------;
  1169. cProc glock,<PUBLIC,NEAR>
  1170. cBegin nogen
  1171. push ax
  1172. inc ch ; Increment lock count
  1173. jz short overflow ; All done if overflow
  1174. mov ds:[esi].pga_count,ch ; Update lock count
  1175. glockerror:
  1176. overflow:
  1177. pop ax
  1178. ret
  1179. cEnd nogen
  1180. ;-----------------------------------------------------------------------;
  1181. ; gunlock ;
  1182. ; ;
  1183. ; Decrement the lock count of an object. ;
  1184. ; ;
  1185. ; Arguments: ;
  1186. ; BX = handle to global object ;
  1187. ; CH = handle table flags ;
  1188. ; CL = lock count for moveable objects ;
  1189. ; CX = handle table flags and lock count for moveable objects ;
  1190. ; DS:DI = address of master object ;
  1191. ; ES:DI = arena header ;
  1192. ; ;
  1193. ; Returns: ;
  1194. ; CX = updated lock count, no underflow ;
  1195. ; ;
  1196. ; Registers Preserved: ;
  1197. ; ;
  1198. ; Registers Destroyed: ;
  1199. ; ;
  1200. ; Calls: ;
  1201. ; glrutop ;
  1202. ; History: ;
  1203. ; ;
  1204. ; Fri Sep 19, 1986 04:39:01p -by- David N. Weise [davidw] ;
  1205. ; Added this nifty comment block. ;
  1206. ;-----------------------------------------------------------------------;
  1207. cProc gunlock,<PUBLIC,NEAR>
  1208. cBegin nogen
  1209. push ax
  1210. mov ax,bx
  1211. dec ch ; Decrement usage count
  1212. cmp ch,0FFh-1 ; ff -> fe, 0 -> ff
  1213. jae short count_zero ; Return if pinned, or was already 0
  1214. dec ds:[esi].pga_count ; Non-zero update lock count
  1215. jnz short count_positive ; All done if still non-zero
  1216. test cl,GA_DISCARDABLE ; Is this a discardable handle?
  1217. jz short count_zero ; No, all done
  1218. call glrutop ; Yes, bring to top of LRU chain
  1219. count_zero:
  1220. xor cx,cx
  1221. count_positive:
  1222. pop ax
  1223. ret
  1224. cEnd nogen
  1225. sEnd CODE
  1226. end