This commit is contained in:
Pavel 2022-10-03 15:00:53 +03:00
parent 23671a5ae5
commit 75d6b8050f
4 changed files with 258 additions and 80 deletions

View File

@ -76,6 +76,7 @@ type
Constructor Create;
private
procedure _Insert(const key:TDirectAdrNode);
procedure _Delete(const key:TDirectAdrNode);
Function _FetchFree_s(ss,se,Size,Align:QWORD;var R:TDirectAdrNode):Boolean;
Function _FetchNode_m(mode:Byte;cmp:QWORD;var R:TDirectAdrNode):Boolean;
Function _Find_m(mode:Byte;var R:TDirectAdrNode):Boolean;
@ -218,6 +219,12 @@ begin
FAllcSet.Insert(key);
end;
procedure TDirectManager._Delete(const key:TDirectAdrNode);
begin
FAllcSet.delete(key);
FFreeSet.delete(key);
end;
//free: [Size] |[Offset]
Function TDirectManager._FetchFree_s(ss,se,Size,Align:QWORD;var R:TDirectAdrNode):Boolean;
var
@ -242,8 +249,7 @@ begin
if (FEndO<=FEndN) then
begin
R:=key;
FAllcSet.delete(key);
FFreeSet.erase(It);
_Delete(key);
Exit(True);
end;
end;
@ -303,8 +309,7 @@ begin
end;
R:=rkey;
FAllcSet.erase(It);
FFreeSet.delete(rkey);
_Delete(rkey);
Result:=True;
end;
@ -720,9 +725,7 @@ begin
if _skip then Break;
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Break;
end;
until false;
@ -822,9 +825,7 @@ begin
if _skip then Break;
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Break;
end;
until false;
@ -916,9 +917,7 @@ begin
if _skip then Break;
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Break;
end;
until false;

View File

@ -18,15 +18,14 @@ uses
offset 12..39:28
size 12..39:28
free 0..0 :1
prot 0..6 :7
reserv 0..0 :1
prot 0..5 :6
addr 12..39:28 ->[direct addr]
reserv 0..0 :1
direct 0..0 :1
stack 0..0 :1
polled 0..0 :1
mapped 0..0 :1
align :3
block Pointer ->[alloc bloc]
]
@ -66,6 +65,7 @@ type
btype :bit8;
used :DWORD;
end;
Handle:Pointer; //gpu
property Offset:Pointer read GetOffset write SetOffset;
property Size:QWORD read GetSize write SetSize;
property Used:QWORD read GetUsed write SetUsed;
@ -92,14 +92,13 @@ type
Offset:bit28;
Size :bit28;
Free :bit1;
prot :bit7;
addr :bit28;
reserv:bit1;
prot :bit6;
addr :bit28;
direct:bit1;
stack :bit1;
polled:bit1;
mapped:bit1;
align :bit3;
end;
block:PVirtualAdrBlock;
property Offset:Pointer read GetOffset write SetOffset;
@ -138,6 +137,7 @@ type
Constructor Create(_lo,_hi:QWORD);
private
procedure _Insert(const key:TVirtualAdrNode);
procedure _Delete(const key:TVirtualAdrNode);
Function _FetchNode_m(mode:Byte;cmp:Pointer;var R:TVirtualAdrNode):Boolean;
Function _Find_m(mode:Byte;var R:TVirtualAdrNode):Boolean;
@ -148,6 +148,7 @@ type
Function _FindFreeOffset(ss:Pointer;Size,Align:QWORD;var AdrOut:Pointer):Integer;
procedure _set_block(Offset:Pointer;Size:QWORD;block:PVirtualAdrBlock);
procedure _mmap_addr(Offset:Pointer;Size,addr:QWORD;direct:Boolean);
procedure _mmap_sys(Offset:Pointer;Size:QWORD);
public
var
OnDirectUnmapCb:TDirectUnmapCb;
@ -164,6 +165,8 @@ type
Function Query(Offset:Pointer;next:Boolean;var ROut:TVirtualAdrNode):Integer;
Function QueryProt(Offset:Pointer;var ROut:TVirtualAdrNode):Integer;
Function TryGetMapBlockByAddr(Offset:Pointer;var block:PVirtualAdrBlock):Boolean;
procedure Print;
end;
@ -173,10 +176,8 @@ uses
mmap;
const
ENOENT= 2;
ENOMEM=12;
EACCES=13;
EBUSY =16;
EINVAL=22;
ENOSYS=78;
@ -437,6 +438,12 @@ begin
FAllcSet.Insert(key);
end;
procedure TVirtualManager._Delete(const key:TVirtualAdrNode);
begin
FAllcSet.delete(key);
FFreeSet.delete(key);
end;
const
M_LE=0;
M_BE=1;
@ -496,8 +503,7 @@ begin
end;
R:=rkey;
FAllcSet.erase(It);
FFreeSet.delete(rkey);
_Delete(rkey);
Result:=True;
end;
@ -611,11 +617,29 @@ var
It:TFreePoolNodeSet.Iterator;
key:TVirtualAdrNode;
Offset:Pointer;
err:Integer;
_qaddr:Pointer;
_qsize:QWORD;
_qflag:Integer;
label
_start;
begin
Result:=0;
_qaddr:=nil;
_qsize:=0;
_qflag:=0;
_start:
key:=Default(TVirtualAdrNode);
key.Offset:=ss;
key.Size :=Size;
It:=FFreeSet.find_be(key);
if (It.Item=nil) then Exit;
repeat
@ -625,6 +649,26 @@ begin
Offset:=System.Align(Max(key.Offset,ss),Align);
if (Offset+Size)<=(key.Offset+key.Size) then
begin
err:=_VirtualQuery(Offset,@_qaddr,@_qsize,nil,@_qflag);
if (err=0) then
begin
if ((_qflag and (MAP_FIXED or MAP_VOID))<>0) then //commit or reserved
begin
_mmap_sys(_qaddr,_qsize);
ss:=Offset;
Goto _start;
end else
if (_qsize<Size) then //not fit
begin
ss:=Offset;
Goto _start;
end;
end else
begin
Assert(false,IntToStr(err));
end;
AdrOut:=Offset;
Exit;
end;
@ -711,9 +755,7 @@ begin
if _map then Break;
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Break;
end;
until false;
@ -785,30 +827,108 @@ begin
if _map then Break;
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Break;
end;
until false;
end;
function _comp_btype(b1,b2:Byte):Integer;
begin
Case b1 of
BT_PRIV,
BT_GPUM:
begin
Case b2 of
BT_PRIV,
BT_GPUM:Result:=0;
else
Result:=ENOSYS; //file map not valid for any devide
end;
end;
else
Result:=ENOSYS;
procedure TVirtualManager._mmap_sys(Offset:Pointer;Size:QWORD);
var
key:TVirtualAdrNode;
FEndN,FEndO:Pointer;
FSize:QWORD;
function _fetch:Boolean;
begin
Result:=False;
if _FetchNode_m(M_LE or C_FR or C_LE,Offset,key) then
begin
FEndN:=Offset+Size;
FEndO:=key.Offset+key.Size;
_Devide(Offset,Size,key);
Result:=True;
end else
if _FetchNode_m(M_BE or C_FR or C_BE,(Offset+Size),key) then
begin
FEndN:=Offset+Size;
FEndO:=key.Offset+key.Size;
_Devide(key.Offset,FEndN-key.Offset,key);
Result:=True;
end;
end;
function _map:Boolean;
begin
Result:=False;
Assert(key.Size<>0);
//new save
key.IsFree :=False;
key.F.addr :=0;
key.F.reserv:=0;
key.F.direct:=0;
key.F.stack :=0;
key.F.polled:=0;
key.F.mapped:=0;
key.block :=nil;
_Merge(key);
if (FEndO>=FEndN) then Exit(True);
FSize:=FEndO-Offset;
Offset:=Offset+FSize;
Size :=Size -FSize;
end;
function _skip:Boolean; inline;
begin
Result:=False;
FEndN:=Offset+Size;
FEndO:=key.Offset+key.Size;
if (FEndO>=FEndN) then Exit(True);
FSize:=FEndO-Offset;
Offset:=Offset+FSize;
Size :=Size -FSize;
end;
begin
if (Size=0) then Exit;
if (Offset<Flo) or (Offset>Fhi) then Exit;
repeat
key:=Default(TVirtualAdrNode);
key.IsFree:=True;
key.Offset:=Offset;
if _fetch then
begin
if _map then Break;
end else
if _Find_m(M_LE,key) then
begin
if _skip then Break;
end else
if _Find_m(M_BE,key) then
begin
if _skip then Break;
end else
begin
Break;
end;
until false;
end;
Function TVirtualManager.check_fixed(Offset:Pointer;Size:QWORD;flags:Byte;fd:Integer):Integer;
@ -851,6 +971,7 @@ begin
end else
begin
if _mapped then Exit(ENOSYS);
if (key.block=nil) then Exit(EINVAL);
if (key.F.reserv=0) then
begin
if not _overwrite then Exit(ENOMEM);
@ -998,7 +1119,6 @@ begin
Result:=_FindFreeOffset(Offset,Size,Align,Offset);
if (Result<>0) then Exit;
flags:=flags or MAP_FIXED;
end;
start:=Offset;
@ -1072,6 +1192,12 @@ begin
Exit(ENOSYS);
end;
if (key.block=nil) then
begin
_Merge(key); //undo
Exit(EINVAL);
end;
if _commited then
begin
if (key.F.reserv=0) then
@ -1107,9 +1233,8 @@ begin
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Result:=EINVAL;
Break;
end;
until false;
@ -1198,6 +1323,7 @@ begin
repeat
key:=Default(TVirtualAdrNode);
key.IsFree:=False;
key.Offset:=Offset;
if _fetch then
@ -1213,9 +1339,7 @@ begin
if _skip then Break;
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Break;
end;
until false;
@ -1304,6 +1428,7 @@ begin
repeat
key:=Default(TVirtualAdrNode);
key.IsFree:=False;
key.Offset:=Offset;
if _fetch then
@ -1319,9 +1444,7 @@ begin
if _skip then Break;
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Break;
end;
until false;
@ -1372,9 +1495,10 @@ var
if (err<>0) then Exit;
end;
key.block^.Free(@key);
block:=key.block;
block^.Free(@key);
if (block^.Used=0) then
begin
@ -1446,12 +1570,19 @@ begin
if _fetch then
begin
if _map then Break;
if (err<>0) then
if (key.block=nil) then
begin
Assert(false,IntToStr(err));
Exit(EINVAL);
if _skip then Break;
end else
begin
if _map then Break;
if (err<>0) then
begin
Assert(false,IntToStr(err));
Exit(EINVAL);
end;
end;
end else
@ -1464,9 +1595,7 @@ begin
if _skip then Break;
end else
begin
if (Size<=$1000) then Break;
Offset:=Offset+$1000;
Size :=Size -$1000;
Break;
end;
until false;
@ -1518,6 +1647,28 @@ begin
ROut:=key;
end;
Function TVirtualManager.TryGetMapBlockByAddr(Offset:Pointer;var block:PVirtualAdrBlock):Boolean;
var
It:TAllcPoolNodeSet.Iterator;
key:TVirtualAdrNode;
begin
Result:=False;
key:=Default(TVirtualAdrNode);
key.Offset:=Offset;
It:=FAllcSet.find_le(key);
if (It.Item=nil) then Exit;
key:=It.Item^;
if key.IsFree then Exit;
if (key.block=nil) then Exit;
block:=key.block;
Result:=True;
end;
function _alloc_str(var key:TVirtualAdrNode):RawByteString;
begin
if (key.F.Free<>0) then

View File

@ -271,28 +271,38 @@ begin
end;
Function TryGetGpuMemBlockByAddr(addr:Pointer;var block:TGpuMemBlock):Boolean;
//var
//_pblock:PBlock;
var
pb:PVirtualAdrBlock;
label
__exit;
begin
Result:=False;
Assert(false,'TODO');
{
pb:=nil;
addr:=AlignDw(addr,PHYSICAL_PAGE_SIZE);
rwlock_rdlock(MMLock);
if PageMM._TryGetMapBlockByAddr(addr,_pblock) then
if VirtualManager.TryGetMapBlockByAddr(addr,pb) then
begin
Case _pblock^.bType of
BT_DIRECT_BIG:
if _isgpu(PBlockBig(_pblock)^.prot) then
begin
block.pAddr :=_pblock^.pAddr;
block.nSize :=_pblock^.nSize;
block.Handle:=PBlockBig(_pblock)^.Handle;
Result:=true;
end;
if (pb^.F.btype<>BT_GPUM) then goto __exit;
if (pb^.Handle=nil) then
begin
if (GpuMemCb.Alloc=nil) then goto __exit;
pb^.Handle:=GpuMemCb.Alloc(pb^.Offset,pb^.Size);
if (pb^.Handle=nil) then goto __exit;
end;
block.pAddr :=pb^.Offset;
block.nSize :=pb^.Size;
block.Handle:=pb^.Handle;
Result:=true;
end;
__exit:
rwlock_unlock(MMLock);
}
end;
Procedure RegistredStack;
@ -1092,6 +1102,11 @@ begin
Writeln('[WARNING] map(addr=0, flags=MAP_FIXED)');
end;
if (addr=nil) then
begin
addr:=Pointer($880000000);
end;
Result:=__mmap(addr,length,alignment,0,flags or MAP_VOID or MAP_SHARED,-1,0,addr);
_set_errno(Result);
@ -1131,6 +1146,11 @@ begin
addr:=virtualAddrDest^;
if not IsAlign(addr,LOGICAL_PAGE_SIZE) then Exit;
if (addr=nil) then
begin
addr:=Pointer($880000000);
end;
Result:=__sys_mmap_dmem(addr,length,alignment,mtype,prots,flags,physicalAddr,addr);
_set_errno(Result);

View File

@ -311,14 +311,22 @@ begin
Result:=GetLastError;
end else
begin
Result:=0;
if (paddr<>nil) then
begin
paddr^:=Info.AllocationBase;
Case Info.State of
MEM_FREE :paddr^:=Info.BaseAddress;
else paddr^:=Info.AllocationBase;
end;
end;
if (psize<>nil) then
begin
psize^:=Info.RegionSize+(ptruint(Info.BaseAddress)-ptruint(Info.AllocationBase));
Case Info.State of
MEM_FREE :psize^:=Info.RegionSize;
else psize^:=Info.RegionSize+(ptruint(Info.BaseAddress)-ptruint(Info.AllocationBase));
end;
end;
if (pprots<>nil) then