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.

1321 lines
54 KiB

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