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.

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