FPPS4/sys/vm/sys_vm_object.pas

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.