2022-05-31 07:17:14 +00:00
|
|
|
unit srAllocator;
|
|
|
|
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2022-09-05 13:30:24 +00:00
|
|
|
ginodes;
|
2022-05-31 07:17:14 +00:00
|
|
|
|
|
|
|
type
|
|
|
|
PsrAllocNode=^TsrAllocNode;
|
|
|
|
TsrAllocNode=packed record
|
|
|
|
pNext:PsrAllocNode;
|
|
|
|
data:record end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
_TsrAllocator=specialize TNodeStack<PsrAllocNode>;
|
|
|
|
TsrAllocator=object(_TsrAllocator)
|
|
|
|
curr_apos:ptruint; //alloc pos in current node
|
|
|
|
curr_size:ptruint; //useable size of current node
|
|
|
|
used_size:ptruint; //full usable size
|
|
|
|
full_size:ptruint; //full alloc size
|
|
|
|
Function Alloc(Size:ptruint):Pointer;
|
|
|
|
Procedure Free;
|
|
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
Function TsrAllocator.Alloc(Size:ptruint):Pointer;
|
|
|
|
const
|
|
|
|
asize=$FFFF-SizeOf(ptruint)*3;
|
|
|
|
var
|
|
|
|
mem_size:ptruint;
|
|
|
|
|
|
|
|
function _alloc:Pointer;
|
|
|
|
begin
|
|
|
|
if (Size>asize-SizeOf(Pointer)) then
|
|
|
|
begin
|
|
|
|
Result:=AllocMem(Size+SizeOf(Pointer));
|
|
|
|
end else
|
|
|
|
begin
|
|
|
|
Result:=AllocMem(asize);
|
|
|
|
end;
|
|
|
|
end;
|
|
|
|
|
|
|
|
begin
|
|
|
|
if (pHead=nil) or (Size>curr_size) then
|
|
|
|
begin
|
|
|
|
Push_head(_alloc);
|
|
|
|
mem_size:=MemSize(pHead);
|
|
|
|
curr_apos:=0;
|
|
|
|
curr_size:=mem_size-SizeOf(Pointer);
|
|
|
|
Inc(full_size,mem_size);
|
|
|
|
end;
|
|
|
|
|
|
|
|
Result:=@PByte(@pHead^.data)[curr_apos];
|
|
|
|
|
|
|
|
Inc(used_size,Size);
|
|
|
|
Size:=Align(Size,SizeOf(ptruint));
|
|
|
|
Inc(curr_apos,Size);
|
|
|
|
Dec(curr_size,Size);
|
|
|
|
end;
|
|
|
|
|
|
|
|
Procedure TsrAllocator.Free;
|
|
|
|
var
|
|
|
|
node:PsrAllocNode;
|
|
|
|
begin
|
|
|
|
node:=Pop_head;
|
|
|
|
While (node<>nil) do
|
|
|
|
begin
|
|
|
|
FreeMem(node);
|
|
|
|
node:=Pop_head;
|
|
|
|
end;
|
|
|
|
curr_apos:=0;
|
|
|
|
curr_size:=0;
|
|
|
|
used_size:=0;
|
|
|
|
full_size:=0;
|
|
|
|
end;
|
|
|
|
|
|
|
|
end.
|
|
|
|
|