mirror of https://github.com/red-prig/fpPS4.git
261 lines
5.8 KiB
Plaintext
261 lines
5.8 KiB
Plaintext
unit sys_vm_object;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
mqueue,
|
|
vm,
|
|
vmparam,
|
|
kern_mtx;
|
|
|
|
type
|
|
obj_type=(
|
|
OBJT_DEFAULT ,//0
|
|
OBJT_SWAP ,//1
|
|
OBJT_VNODE ,//2
|
|
OBJT_DEVICE ,//3
|
|
OBJT_PHYS ,//4
|
|
OBJT_DEAD ,//5
|
|
OBJT_SG ,//6
|
|
OBJT_JITSHM ,//7
|
|
OBJT_SELF ,//8
|
|
OBJT_TRCMEM ,//9
|
|
OBJT_PHYSHM ,//10
|
|
OBJT_BLOCKPOOL //11
|
|
);
|
|
|
|
objtype_t=obj_type;
|
|
|
|
p_vm_object_t=^vm_object_t;
|
|
vm_object_t=^t_vm_object;
|
|
t_vm_object=record
|
|
mtx :mtx;
|
|
patchq :TAILQ_HEAD; // list of patches
|
|
size :vm_pindex_t; // Object size
|
|
generation:Integer; // generation ID
|
|
ref_count :Integer; // How many refs??
|
|
otype :objtype_t; // type of pager
|
|
pg_color :Word;
|
|
flags :Word; // see below
|
|
pip :Integer;
|
|
budget_id :Integer;
|
|
handle :Pointer;
|
|
un_pager :record
|
|
map_base:Pointer;
|
|
vnp:record
|
|
vnp_size:QWORD;
|
|
writemappings:vm_ooffset_t;
|
|
end;
|
|
physhm:record
|
|
mtype :Byte;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
const
|
|
//Flags
|
|
OBJ_ACTIVE =$0004; // active objects
|
|
OBJ_DEAD =$0008; // dead objects (during rundown)
|
|
OBJ_NOSPLIT =$0010; // dont split this object
|
|
OBJ_PIPWNT =$0040; // paging in progress wanted
|
|
OBJ_MIGHTBEDIRTY =$0100; // object might be dirty, only for vnode
|
|
OBJ_COLORED =$1000; // pg_color is defined
|
|
OBJ_ONEMAPPING =$2000; // One USE (a single, non-forked) mapping flag
|
|
OBJ_DISCONNECTWNT=$4000; // disconnect from vnode wanted
|
|
OBJ_DMEM_EXT =$8000; // direct memory
|
|
OBJ_JITSHM_EXT =$0020; // jitshim memory
|
|
OBJ_WIRE_BUDGET =$0080; // wire state in budget
|
|
|
|
OBJPC_SYNC =$1; // sync I/O
|
|
OBJPC_INVAL =$2; // invalidate
|
|
OBJPC_NOSYNC=$4; // skip if PG_NOSYNC
|
|
|
|
//The following options are supported by vm_object_page_remove().
|
|
OBJPR_CLEANONLY=$1; // Don't remove dirty pages.
|
|
OBJPR_NOTMAPPED=$2; // Don't unmap pages.
|
|
OBJPR_NOTWIRED =$4; // Don't remove wired pages.
|
|
|
|
function VM_OBJECT_MTX(obj:vm_object_t):p_mtx;
|
|
procedure VM_OBJECT_LOCK(obj:vm_object_t);
|
|
function VM_OBJECT_TRYLOCK(obj:vm_object_t):Boolean;
|
|
procedure VM_OBJECT_UNLOCK(obj:vm_object_t);
|
|
function VM_OBJECT_LOCKED(obj:vm_object_t):Boolean;
|
|
procedure VM_OBJECT_LOCK_ASSERT(obj:vm_object_t);
|
|
|
|
procedure vm_object_set_flag(obj:vm_object_t;bits:Word);
|
|
procedure vm_object_clear_flag(obj:vm_object_t;bits:Word);
|
|
|
|
procedure vm_object_set_budget(obj:vm_object_t;budget_id:Integer);
|
|
|
|
function vm_object_allocate(t:objtype_t;size:vm_pindex_t):vm_object_t;
|
|
procedure vm_object_destroy(obj:vm_object_t);
|
|
procedure vm_object_reference(obj:vm_object_t);
|
|
|
|
procedure vm_object_pip_add(obj:vm_object_t;i:word);
|
|
procedure vm_object_pip_subtract(obj:vm_object_t;i:word);
|
|
function vm_object_type(obj:vm_object_t):obj_type;
|
|
|
|
procedure vm_object_patch_remove(_obj:Pointer;start,__end:DWORD); external;
|
|
|
|
procedure vm_object_deallocate(obj:vm_object_t); external;
|
|
|
|
procedure vm_object_collapse(obj:vm_object_t); external;
|
|
|
|
function vm_object_coalesce(prev_object:vm_object_t;
|
|
prev_offset:vm_ooffset_t;
|
|
prev_size :vm_ooffset_t;
|
|
next_size :vm_ooffset_t;
|
|
reserved :Boolean):Boolean; external;
|
|
|
|
procedure vm_object_page_remove(obj:vm_object_t;
|
|
start:vm_pindex_t;
|
|
__end:vm_pindex_t;
|
|
options:Integer); external;
|
|
|
|
function vm_object_page_clean(obj:vm_object_t;
|
|
start,__end:vm_ooffset_t;
|
|
flags:Integer):Boolean; external;
|
|
|
|
implementation
|
|
|
|
uses
|
|
vnode;
|
|
|
|
//
|
|
|
|
procedure vref(vp:p_vnode); external;
|
|
|
|
//
|
|
|
|
function VM_OBJECT_MTX(obj:vm_object_t):p_mtx;
|
|
begin
|
|
Result:=@obj^.mtx;
|
|
end;
|
|
|
|
procedure VM_OBJECT_LOCK(obj:vm_object_t);
|
|
begin
|
|
mtx_lock(obj^.mtx);
|
|
end;
|
|
|
|
function VM_OBJECT_TRYLOCK(obj:vm_object_t):Boolean;
|
|
begin
|
|
Result:=mtx_trylock(obj^.mtx);
|
|
end;
|
|
|
|
procedure VM_OBJECT_UNLOCK(obj:vm_object_t);
|
|
begin
|
|
mtx_unlock(obj^.mtx);
|
|
end;
|
|
|
|
function VM_OBJECT_LOCKED(obj:vm_object_t):Boolean;
|
|
begin
|
|
Result:=(mtx_owned(obj^.mtx));
|
|
end;
|
|
|
|
procedure VM_OBJECT_LOCK_ASSERT(obj:vm_object_t);
|
|
begin
|
|
Assert(mtx_owned(obj^.mtx));
|
|
end;
|
|
|
|
procedure vm_object_set_flag(obj:vm_object_t;bits:Word);
|
|
begin
|
|
VM_OBJECT_LOCK_ASSERT(obj);
|
|
obj^.flags:=obj^.flags or bits;
|
|
end;
|
|
|
|
procedure vm_object_clear_flag(obj:vm_object_t;bits:Word);
|
|
begin
|
|
VM_OBJECT_LOCK_ASSERT(obj);
|
|
obj^.flags:=obj^.flags and (not bits);
|
|
end;
|
|
|
|
procedure vm_object_set_budget(obj:vm_object_t;budget_id:Integer);
|
|
begin
|
|
obj^.budget_id:=budget_id;
|
|
end;
|
|
|
|
function vm_object_allocate(t:objtype_t;size:vm_pindex_t):vm_object_t;
|
|
begin
|
|
Result:=AllocMem(SizeOf(t_vm_object));
|
|
|
|
mtx_init(Result^.mtx,'vm_object');
|
|
|
|
TAILQ_INIT(@Result^.patchq);
|
|
|
|
Result^.otype :=t;
|
|
Result^.size :=size;
|
|
Result^.generation:=1;
|
|
Result^.ref_count :=1;
|
|
|
|
Result^.budget_id :=-1;
|
|
//Result^.vm_container:=0;
|
|
|
|
case t of
|
|
OBJT_DEFAULT:
|
|
begin
|
|
Result^.flags:=OBJ_ONEMAPPING;
|
|
end;
|
|
else;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure vm_object_destroy(obj:vm_object_t);
|
|
begin
|
|
mtx_destroy(obj^.mtx);
|
|
|
|
FreeMem(obj);
|
|
end;
|
|
|
|
procedure vm_object_reference(obj:vm_object_t);
|
|
begin
|
|
if (obj=nil) then Exit;
|
|
|
|
VM_OBJECT_LOCK(obj);
|
|
|
|
Inc(obj^.ref_count);
|
|
|
|
if (obj^.otype=OBJT_VNODE) then
|
|
begin
|
|
if (obj^.otype=OBJT_VNODE) then
|
|
begin
|
|
vref(obj^.handle);
|
|
end;
|
|
end;
|
|
|
|
VM_OBJECT_UNLOCK(obj);
|
|
end;
|
|
|
|
procedure vm_object_pip_add(obj:vm_object_t;i:word);
|
|
begin
|
|
if (obj=nil) then Exit;
|
|
|
|
VM_OBJECT_LOCK_ASSERT(obj);
|
|
obj^.pip:=obj^.pip+i;
|
|
end;
|
|
|
|
procedure vm_object_pip_subtract(obj:vm_object_t;i:word);
|
|
begin
|
|
if (obj=nil) then Exit;
|
|
|
|
VM_OBJECT_LOCK_ASSERT(obj);
|
|
obj^.pip:=obj^.pip-i;
|
|
end;
|
|
|
|
function vm_object_type(obj:vm_object_t):obj_type;
|
|
begin
|
|
if (obj=nil) then Exit(OBJT_DEFAULT);
|
|
|
|
Result:=obj^.otype;
|
|
end;
|
|
|
|
|
|
end.
|
|
|
|
|
|
|
|
|