home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 514b.lha / ToolLib_v8.1 / Source / mem.s < prev    next >
Text File  |  1991-06-08  |  15KB  |  300 lines

  1.             opt     l+,o+,ow-
  2. *
  3. *   mem.s version 8.1 - © Copyright 1990 Jaba Development
  4. *
  5. *   Author    : Jan van den Baard
  6. *   Assembler : Devpac vesion 2.14
  7. *
  8. *   Memory allocation/freeing routines that prevent memory fragmentizing when
  9. *   a lot of small allocations/deallocations are made.
  10. *
  11.                 incdir  'sys:devpac_inc/'
  12.                 include 'mymacros.i'
  13.                 include 'tool.i'
  14.                 include 'exec/exec_lib.i'
  15.  
  16.                 xdef    InitMemoryChain
  17.                 xdef    AllocItem
  18.                 xdef    FreeItem
  19.                 xdef    FreeMemoryChain
  20.  
  21. InitMemoryChain:
  22.                 move.l  a0,a1                   ; chain to a1
  23.                 lea.l   mc_Blocks(a1),a0
  24.                 NEWLIST a0                      ; initialize block list
  25.                 lea.l   mc_Items(a1),a0
  26.                 NEWLIST a0                      ; initialize item list
  27.                 LONGALLIGN  d0                  ; allign the block size
  28.                 move.l  d0,mc_BlockSize(a1)     ; put it in the structure
  29.                 rts
  30.  
  31. FreeBlock:      movem.l a2-a3/a5-a6,-(sp)
  32.                 move.l  a0,a2                   ; chain to a2
  33.                 move.l  a1,a3                   ; block to a3
  34.                 lea.l   mc_Items(a2),a5
  35.                 move.l  il_First(a5),a5         ; first item in a5
  36. FBLoop:         tst.l   mit_Next(a5)            ; is there a next item ?
  37.                 beq.s   FBDone                  ; no.. done
  38.                 cmp.l   mit_Block(a5),a3        ; item in the block ?
  39.                 bne.s   FBNotSame               ; no.. get next item
  40.                 move.l  a5,a1
  41.                 REMOVE                          ; remove item from the list
  42.                 lea.l   mc_Items(a2),a5
  43.                 move.l  il_First(a5),a5
  44.                 bra.s   FBLoop                  ; start from the begin
  45. FBNotSame:      move.l  mit_Next(a5),a5
  46.                 bra.s   FBLoop                  ; try the next item
  47. FBDone:         move.l  a3,a1
  48.                 REMOVE                          ; remove block from the list
  49.                 move.l  (_SysBase).w,a6
  50.                 move.l  a3,a1
  51.                 move.l  mc_BlockSize(a2),d0
  52.                 add.l   #mb_SIZEOF,d0
  53.                 libcall FreeMem                 ; free the block's memory
  54.                 movem.l (sp)+,a2-a3/a5-a6
  55.                 rts
  56.  
  57. AllocBlock:     movem.l d2/a2-a3/a5-a6,-(sp)
  58.                 move.l  a0,a2                   ; chain to a2
  59.                 move.l  d0,d2                   ; reqs to d2
  60.                 move.l  d2,d1
  61.                 move.l  mc_BlockSize(a2),d0
  62.                 add.l   #mb_SIZEOF,d0
  63.                 move.l  (_SysBase).w,a6
  64.                 libcall AllocMem                ; allocate the memory
  65.                 move.l  d0,a3                   ; put it in a3
  66.                 beq.s   ABNoMem
  67.                 move.l  d2,mb_Requirements(a3)  ; set block reqs
  68.                 clr.l   mb_BytesUsed(a3)        ; clear bytes used counter
  69.                 lea.l   mc_Blocks(a2),a0
  70.                 move.l  a3,a1
  71.                 ADDHEAD                         ; add block in the list
  72.                 move.l  a3,a5
  73.                 add.l   #mb_SIZEOF,a5           ; get first item in a5
  74.                 move.l  a3,mit_Block(a5)        ; set it's block
  75.                 move.l  mc_BlockSize(a2),mit_Size(a5) ; set it's size
  76.                 lea.l   mc_Items(a2),a0
  77.                 move.l  a5,a1
  78.                 ADDHEAD                         ; add item in the list
  79.                 move.l  a3,d0                   ; return the block
  80. ABEnd:          movem.l (sp)+,d2/a2-a3/a5-a6
  81.                 rts
  82. ABNoMem:        cldat   d0                      ; alloc failed.. return 0
  83.                 bra.s   ABEnd
  84.  
  85.  
  86. OptimizeBlock:  link    a6,#-il_SIZEOF          ; create stack space
  87.                 movem.l d2/a2-a6,-(sp)
  88.                 move.l  a0,a2                   ; chain to a2
  89.                 move.l  a1,a3                   ; block to a3
  90.                 lea.l   -il_SIZEOF(a6),a0
  91.                 NEWLIST a0                      ; init buffer list
  92.                 lea.l   mc_Items(a2),a4
  93.                 move.l  il_First(a4),a4         ; first item to a4
  94. OBLoop1:        tst.l   mit_Next(a4)            ; is there a next item ?
  95.                 beq.s   OBDone1                 ; no.. done
  96.                 cmp.l   mit_Block(a4),a3        ; item in the block ?
  97.                 bne.s   OBNotSame1              ; no.. skip it
  98.                 move.l  a4,a1
  99.                 REMOVE                          ; remove item
  100.                 lea.l   -il_SIZEOF(a6),a0
  101.                 move.l  a4,a1
  102.                 ADDTAIL                         ; put item in buffer list
  103.                 lea.l   mc_Items(a2),a4
  104.                 move.l  il_First(a4),a4
  105.                 bra.s   OBLoop1                 ; start from the begin
  106. OBNotSame1:     move.l  mit_Next(a4),a4
  107.                 bra.s   OBLoop1                 ; try the next item
  108. OBDone1:        lea.l   -il_SIZEOF(a6),a0
  109.                 move.l  il_First(a0),a4         ; first buffer item in a4
  110. OBLoop2:        tst.l   mit_Next(a4)            ; is there a next item ?
  111.                 beq.s   OBDone2                 ; no.. done
  112.                 move.l  a4,d2
  113.                 add.l   mit_Size(a4),d2         ; addres behind item to d2
  114.                 move.l  a4,a5
  115. OBLoop3:        tst.l   mit_Next(a5)            ; is there a next item ?
  116.                 beq.s   OBDone3                 ; no.. done
  117.                 cmp.l   d2,a5                   ; d2 is a5 ?
  118.                 bne.s   OBNotSame2              ; no.. skip it
  119.                 move.l  mit_Size(a5),d0
  120.                 add.l   d0,mit_Size(a4)         ; join a4 with a5
  121.                 add.l   d0,d2
  122.                 move.l  a5,a1
  123.                 REMOVE                          ; remove a5 from the list
  124.                 lea.l   -il_SIZEOF(a6),a0
  125.                 move.l  il_First(a0),a5
  126.                 bra.s   OBLoop3                 ; start from the begin
  127. OBNotSame2:     move.l  mit_Next(a5),a5
  128.                 bra.s   OBLoop3                 ; try the next item
  129. OBDone3:        move.l  mit_Next(a4),a4
  130.                 bra.s   OBLoop2                 ; try the next item
  131. OBDone2:        lea.l   -il_SIZEOF(a6),a0
  132.                 REMHEAD                         ; remove item from the buffer
  133.                 tst.l   d0                      ; is it 0 ?
  134.                 beq.s   NoMore                  ; yes.. all done
  135.                 move.l  d0,a1
  136.                 lea.l   mc_Items(a2),a0
  137.                 ADDHEAD                         ; add it to the list
  138.                 bra.s   OBDone2
  139. NoMore:         movem.l (sp)+,d2/a2-a6
  140.                 unlk    a6
  141.                 rts
  142.  
  143. OptimizeChain:  movem.l a2-a3,-(sp)
  144.                 move.l  a0,a2                   ; chain to a2
  145.                 lea.l   mc_Blocks(a2),a3
  146.                 move.l  bl_First(a3),a3         ; first block in a2
  147. OCLoop:         tst.l   mb_Next(a3)             ; is there a next block ?
  148.                 beq.s   OCDone                  ; no.. done
  149.                 move.l  a2,a0
  150.                 move.l  a3,a1
  151.                 bsr     OptimizeBlock           ; optimize it
  152.                 move.l  mb_Next(a3),a3          ; next patient please..
  153.                 bra.s   OCLoop
  154. OCDone:         movem.l (sp)+,a2-a3
  155.                 rts
  156.  
  157. FindSpace:      movem.l d2-d3/a2-a3,-(sp)
  158.                 move.l  a0,a2                   ; chain to a2
  159.                 move.l  d0,d2                   ; size to d2
  160.                 move.l  d1,d3                   ; reqs to d3
  161.                 lea.l   mc_Items(a2),a3
  162.                 move.l  il_First(a3),a3         ; first item to a3
  163. FSLoop:         tst.l   mit_Next(a3)            ; is there a next item ?
  164.                 beq.s   FSDone                  ; no.. done
  165.                 move.l  mit_Block(a3),a0
  166.                 cmp.l   mb_Requirements(a0),d3  ; requirements OK ?
  167.                 bne.s   FSNotSame               ; no.. skip it
  168.                 cmp.l   mit_Size(a3),d2         ; size OK ?
  169.                 bhi.s   FSNotSame               ; no.. skip it
  170.                 move.l  a3,d0                   ; return the item
  171.                 bra.s   FSEnd
  172. FSNotSame:      move.l  mit_Next(a3),a3
  173.                 bra.s   FSLoop                  ; try the next item
  174. FSDone:         cldat   d0                      ; no item found
  175. FSEnd:          movem.l (sp)+,d2-d3/a2-a3
  176.                 rts
  177.  
  178. AllocItem:      movem.l d2-d4/a2-a5,-(sp)
  179.                 move.l  a0,a2                   ; chain to a2
  180.                 move.l  d0,d2                   ; size to d2
  181.                 move.l  d1,d3                   ; reqs to d3
  182.                 bclr.l  #16,d3                  ; clear MEMF_CLEAR   bit
  183.                 bclr.l  #17,d3                  ; clear MEMF_LARGEST bit
  184.                 cmp.l   #mit_SIZEOF,d2          ; size > mit_SIZEOF ?
  185.                 bhi.s   ASOK                    ; yes.. ok
  186.                 move.l  #mit_SIZEOF,d2          ; else make it that big
  187. ASOK:           LONGALLIGN  d2                  ; allign the size
  188.                 cmp.l   mc_BlockSize(a2),d2
  189.                 bhi.s   NoMem
  190.                 move.l  d3,d1
  191.                 move.l  d2,d0
  192.                 move.l  a2,a0
  193.                 bsr     FindSpace               ; find a suitable item
  194.                 move.l  d0,a4                   ; put it in a4
  195.                 bne.s   HaveSpace               ; found one..
  196.                 move.l  d3,d0
  197.                 move.l  a2,a0
  198.                 bsr     AllocBlock              ; allocate a block
  199.                 move.l  d0,a4                   ; put it in a4
  200.                 beq     NoMem                   ; no more memory (wheeee)
  201.                 add.l   #mb_SIZEOF,a4           ; get first item
  202. HaveSpace:      move.l  mit_Block(a4),a3        ; get block in a3
  203.                 cmp.l   mit_Size(a4),d2         ; size equals item size ?
  204.                 beq.s   NoSplit                 ; yes.. don't split it
  205.                 move.l  mit_Size(a4),d4
  206.                 sub.l   d2,d4
  207.                 cmp.l   #mit_SIZEOF,d4          ; size left < mit_SIZEOF ?
  208.                 bcs.s   NoSplit                 ; yes.. don't split it
  209.                 move.l  a4,a5
  210.                 add.l   d2,a5                   ; new item in a5
  211.                 move.l  d4,mit_Size(a5)         ; set new item size
  212.                 move.l  a3,mit_Block(a5)        ; set new item block
  213.                 lea.l   mc_Items(a2),a0
  214.                 move.l  a5,a1
  215.                 ADDHEAD                         ; add it in the list
  216. NoSplit:        move.l  a4,a1
  217.                 REMOVE                          ; remove it from the list
  218.                 move.l  a4,a0
  219.                 move.l  d2,d0
  220.                 bsr     ClearAlloc              ; clear memory
  221.                 add.l   d2,mb_BytesUsed(a3)     ; increase bytes used counter
  222.                 move.l  a4,d0                   ; return the pointer
  223. AIEnd:          movem.l (sp)+,d2-d4/a2-a5
  224.                 rts
  225. NoMem:          cldat   d0                      ; no memory.. return 0
  226.                 bra.s   AIEnd
  227.  
  228. FreeItem:       movem.l d2/a2-a4,-(sp)
  229.                 move.l  a0,a2                   ; chain to a2
  230.                 move.l  a1,a3                   ; memptr to a3
  231.                 move.l  d0,d2                   ; size to d2
  232.                 cmp.l   #mit_SIZEOF,d2          ; size > mit_SIZEOF ?
  233.                 bhi.s   FSOK                    ; yes.. ok
  234.                 move.l  #mit_SIZEOF,d2          ; else make it that big
  235. FSOK:           LONGALLIGN  d2                  ; allign the size
  236.                 bsr     FindBlock               ; find it's block
  237.                 move.l  d0,a4                   ; and put it in a4
  238.                 beq     FRDone                  ; block 0.. don't free
  239.                 move.l  a4,mit_Block(a3)        ; set item block
  240.                 move.l  d2,mit_Size(a3)         ; set item size
  241.                 sub.l   d2,mb_BytesUsed(a4)     ; decrease bytes used count
  242.                 move.l  a3,a1
  243.                 lea.l   mc_Items(a2),a0
  244.                 ADDHEAD                         ; add item in the list
  245.                 tst.l   mb_BytesUsed(a4)
  246.                 bne.s   FROpt                   ; block not free
  247.                 move.l  mit_Block(a3),a1
  248.                 move.l  a2,a0
  249.                 bsr     FreeBlock               ; free the block
  250. FROpt:          move.l  a2,a0
  251.                 bsr     OptimizeChain           ; optimize the chain
  252. FRDone:         movem.l (sp)+,d2/a2-a4
  253.                 rts
  254.  
  255. FindBlock:      move.l  a2,-(sp)
  256.                 lea.l   mc_Blocks(a0),a2
  257.                 move.l  bl_First(a2),a2         ; first block to a2
  258. FBBLoop:        tst.l   mb_Next(a2)             ; is there a next block ?
  259.                 beq.s   FBBDone                 ; no.. done
  260.                 move.l  a2,d0
  261.                 cmp.l   d0,a1                   ; memptr < block start ?
  262.                 bmi.s   FBBNotSame              ; yes.. skip it
  263.                 add.l   #mb_SIZEOF,d0
  264.                 add.l   mc_BlockSize(a0),d0
  265.                 cmp.l   d0,a1                   ; memptr > block end ?
  266.                 bhi.s   FBBNotSame              ; yes.. skip it
  267.                 move.l  a2,d0                   ; return block
  268.                 bra.s   EndFBB
  269. FBBNotSame:     move.l  mb_Next(a2),a2
  270.                 bra.s   FBBLoop                 ; try the next block
  271. FBBDone:        cldat   d0                      ; block not found.. return 0
  272. EndFBB:         move.l  (sp)+,a2
  273.                 rts
  274.  
  275. FreeMemoryChain:
  276.                 movem.l a2-a3/a6,-(sp)
  277.                 move.l  a0,a2                   ; chain to a2
  278.                 move.l  (_SysBase).w,a6
  279. FMCLoop:        lea.l   mc_Blocks(a2),a0
  280.                 REMHEAD                         ; remove a block
  281.                 move.l  d0,a1                   ; put it in a1
  282.                 beq.s   AllDone                 ; block 0 then done
  283.                 move.l  mc_BlockSize(a2),d0
  284.                 add.l   #mb_SIZEOF,d0
  285.                 libcall FreeMem                 ; free it's memory
  286.                 bra.s   FMCLoop
  287. AllDone:        move.l  mc_BlockSize(a2),d0
  288.                 move.l  a2,a0
  289.                 bsr     InitMemoryChain         ; re-initialize the chain
  290.                 movem.l (sp)+,a2-a3/a6
  291.                 rts
  292.  
  293. ClearAlloc:     lsr.l   #2,d0                   ; size / 2
  294.                 dec.l   d0
  295. Loop:           clr.l   (a0)+                   ; clear a long word
  296.                 dbra    d0,Loop
  297.                 rts
  298.  
  299.  
  300.