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

View File

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

View File

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

View File

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