; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Dynamic memory management library.
;
;  Target OS: Any
;
;  Dependencies:
;
;  Notes: This file contains the OS independent part of the library and includes the
;         respective OS dependent file.
;_________________________________________________________________________________________

module "Memory library"

DebugMemory = 0
cInitialCapacity = 10


; Allocates memory block with given size.
; Returns: CF=1 if error.
;          if CF=0, eax = pointer to the memory block allocated.
interface GetMem, .size

interface FreeMem, .ptr

interface ResizeMem, .ptr, .newsize

interface SpaceAllocate, .size


match =HeapManager, HeapManager {
  define HeapManager OS
}

match =OS, HeapManager {
  include '%TargetOS%/memory.asm'
}

match =ASM, HeapManager {
  include 'heapmgr.asm'
}


  ;___________________________________________________________________________
  ;
  ; This is a pointer to the active resize strategy procedure.
  ; There can be many different strategies for resizing dynamic memory objects.
  ; ResizeIt points to a procedure that resizes ecx, according to the particular
  ; strategy.
  ; The resize procedure returns CF=1 if the resize can not be provided.
  ;____________________________________________________________________________
  if used ResizeIt
    ResizeIt dd StrategyMedium
  end if

uglobal
  var _MemoryFreeSpace=?
endg

;____________________________
;
; NewSize = (OldSize+1)*2
; Very aggressive strategy.
;____________________________

proc StrategyAgressive
begin
        add     ecx, 1
        jc      @f
        shl     ecx, 1
@@:
        return
endp



;____________________________
;
; NewSize = (OldSize+2)*1.5
; Normal strategy.
;____________________________

proc StrategyMedium
begin
        push    ecx
        add     ecx, 1
        jc      .exit
        shr     ecx, 1
        add     [esp], ecx
        pop     ecx

        cmp     ecx, cInitialCapacity
        jae     .exit
        mov     ecx, cInitialCapacity
        clc
.exit:
        return
endp


;____________________________
;
; NewSize = (OldSize+2)*1.25
; Memory spare strategy.
;____________________________

proc StrategyGentle
begin
        push    ecx
        add     ecx, 1
        jc      .exit
        shr     ecx, 2
        add     [esp], ecx
        pop     ecx

        cmp     ecx, cInitialCapacity
        jae     .exit
        mov     ecx, cInitialCapacity
        clc
.exit:
        return
endp


endmodule