diff --git a/sys/dev/dev_dce.pas b/sys/dev/dev_dce.pas index d62b1356..7e13759b 100644 --- a/sys/dev/dev_dce.pas +++ b/sys/dev/dev_dce.pas @@ -634,7 +634,7 @@ begin end; obj:=vm_pager_allocate(OBJT_DEVICE,cdev,PAGE_SIZE,$33,off); - obj^.map_base:=Pointer(@dce_page)-PAGE_SIZE; + obj^.un_pager.map_base:=Pointer(@dce_page)-PAGE_SIZE; if (obj=nil) then begin diff --git a/sys/dev/dev_dmem.pas b/sys/dev/dev_dmem.pas index dc9201d1..356e41e8 100644 --- a/sys/dev/dev_dmem.pas +++ b/sys/dev/dev_dmem.pas @@ -141,7 +141,7 @@ begin Exit(-1); end; - paddr^:=offset + QWORD(dmap^.vobj^.map_base); + paddr^:=offset + QWORD(dmap^.vobj^.un_pager.map_base); memattr^:=0; end; @@ -246,7 +246,7 @@ begin obj:=vm_pager_allocate(OBJT_DEVICE,dev,0,0,0); obj^.size:=$1400000; obj^.flags:=obj^.flags or OBJ_DMEM_EXT; - obj^.map_base:=Pointer(VM_MIN_GPU_ADDRESS); + obj^.un_pager.map_base:=Pointer(VM_MIN_GPU_ADDRESS); vm_object_reference(obj); // dmem_maps[i].dmem:=@kern_dmem.dmem; diff --git a/sys/dev/dev_gc.pas b/sys/dev/dev_gc.pas index c0966ebb..7840c65c 100644 --- a/sys/dev/dev_gc.pas +++ b/sys/dev/dev_gc.pas @@ -130,7 +130,7 @@ begin end; obj:=vm_pager_allocate(OBJT_DEVICE,cdev,PAGE_SIZE,nprot,offset^); - obj^.map_base:=@gc_page; + obj^.un_pager.map_base:=@gc_page; if (obj=nil) then begin diff --git a/sys/kern/kern_authinfo.pas b/sys/kern/kern_authinfo.pas index 11c84a48..65435f83 100644 --- a/sys/kern/kern_authinfo.pas +++ b/sys/kern/kern_authinfo.pas @@ -53,12 +53,15 @@ type const //SceLncAppType - SCE_LNC_APP_TYPE_INVALID =-1; - SCE_LNC_APP_TYPE_SHELL_UI= 1; //isSystemApp - SCE_LNC_APP_TYPE_DAEMON = 2; //isSystemApp - SCE_LNC_APP_TYPE_CDLG = 3; //isSystemApp - SCE_LNC_APP_TYPE_MINI_APP= 4; //isSystemApp - SCE_LNC_APP_TYPE_BIG_APP = 5; + SCE_LNC_APP_TYPE_INVALID =-1; + SCE_LNC_APP_TYPE_NULL = 0; + SCE_LNC_APP_TYPE_SHELL_UI = 1; //isSystemApp + SCE_LNC_APP_TYPE_DAEMON = 2; //isSystemApp + SCE_LNC_APP_TYPE_CDLG = 3; //isSystemApp + SCE_LNC_APP_TYPE_MINI_APP = 4; //isSystemApp + SCE_LNC_APP_TYPE_BIG_APP = 5; + SCE_LNC_APP_TYPE_SHELL_CORE= 6; //isSystemApp + SCE_LNC_APP_TYPE_SHELL_APP = 7; //isSystemApp //[preloadPrxFlags] -> sceSysmodulePreloadModuleForLibkernel //0x0000000004 libSceNet @@ -108,7 +111,7 @@ type AppId :Integer; //4 mmap_flags :Integer; //4 attributeExe :Integer; //4 - AppType :Integer; //4 SceLncAppType + attribute2 :Integer; //4 CUSANAME :TCUSANAME; //10 titleId debug_level :Byte; //1 slv_flags :Byte; //1 eLoadOptions diff --git a/sys/kern/kern_dmem.pas b/sys/kern/kern_dmem.pas index 59fabad7..415e691a 100644 --- a/sys/kern/kern_dmem.pas +++ b/sys/kern/kern_dmem.pas @@ -265,6 +265,8 @@ begin if (err=0) then begin + vm_object_reference(dmap.vobj); + err:=vm_map_insert(map, dmap.vobj, phaddr, vaddr, v_end, prot, VM_PROT_ALL, cow, ((p_proc.p_dmem_aliasing and 3)<>0)); if (err=0) then @@ -272,6 +274,8 @@ begin addr^:=vaddr; end else begin + vm_object_deallocate(dmap.vobj); + // Result:=vm_mmap_to_errno(err); end; end; diff --git a/sys/kern/kern_exec.pas b/sys/kern/kern_exec.pas index 4a2ee546..0a46e4e9 100644 --- a/sys/kern/kern_exec.pas +++ b/sys/kern/kern_exec.pas @@ -1310,9 +1310,9 @@ begin if (error<>0) then goto exec_fail_dealloc; //imgp^.obj:=imgp^.vp^.v_object; - //if (imgp^.object<>nil) then + //if (imgp^.obj<>nil) then //begin - // vm_object_reference(imgp^.object); + // vm_object_reference(imgp^.obj); //end; error:=rtld_load_self(imgp); @@ -1457,7 +1457,6 @@ begin begin g_appinfo.mmap_flags:=g_appinfo.mmap_flags or 2; //is_system ??? end; - g_appinfo.AppType:=SCE_LNC_APP_TYPE_BIG_APP; //TODO load CUSANAME diff --git a/sys/kern/kern_rtld.pas b/sys/kern/kern_rtld.pas index d718bcf3..b0f228a0 100644 --- a/sys/kern/kern_rtld.pas +++ b/sys/kern/kern_rtld.pas @@ -1084,11 +1084,15 @@ begin //remove prev if exist vm_map_delete(map,vaddr_lo,vaddr_hi,True); + vm_object_reference(imgp^.obj); + Result:=vm_map_insert(map,imgp^.obj,offset,vaddr_lo,vaddr_hi,VM_PROT_RW,prot or VM_PROT_RW,0,false); if (Result<>0) then begin vm_map_unlock(map); // + vm_object_deallocate(imgp^.obj); + // Writeln(StdErr,'[KERNEL] self_load_section: vm_map_insert failed ',id,', ',HexStr(vaddr,8)); Exit(vm_mmap_to_errno(Result)); end; diff --git a/sys/md/md_map.pas b/sys/md/md_map.pas index 646164e9..e7fd48a1 100644 --- a/sys/md/md_map.pas +++ b/sys/md/md_map.pas @@ -31,6 +31,9 @@ function md_reset (base:Pointer;size:QWORD;prot:Integer):Integer; function md_mmap (var base:Pointer;size:QWORD;prot:Integer):Integer; function md_unmap (base:Pointer;size:QWORD):Integer; +function md_file_mmap (handle:THandle;var base:Pointer;offset,size:QWORD;prot:Integer):Integer; +function md_file_unmap(base:Pointer;size:QWORD):Integer; + const ICACHE=1; //Flush the instruction cache. DCACHE=2; //Write back to memory and invalidate the affected valid cache lines. @@ -146,6 +149,65 @@ begin ); end; +function md_file_mmap(handle:THandle;var base:Pointer;offset,size:QWORD;prot:Integer):Integer; +var + hSection:THandle; + DesiredAccess:DWORD; + CommitSize:ULONG_PTR; + SectionOffset:ULONG_PTR; + ViewSize:ULONG_PTR; +begin + + case prot of + PAGE_READWRITE :DesiredAccess:=SECTION_MAP_READ or SECTION_MAP_WRITE; + PAGE_EXECUTE :DesiredAccess:=SECTION_MAP_EXECUTE; + PAGE_EXECUTE_READ :DesiredAccess:=SECTION_MAP_EXECUTE or SECTION_MAP_READ; + PAGE_EXECUTE_READWRITE:DesiredAccess:=SECTION_MAP_EXECUTE or SECTION_MAP_READ or SECTION_MAP_WRITE; + else + DesiredAccess:=SECTION_MAP_READ; + end; + + hSection:=0; + Result:=NtCreateSection( + @hSection, + DesiredAccess, + nil, + @size, + prot, + SEC_COMMIT, + handle + ); + + if (Result<>0) then Exit; + + base:=md_alloc_page(base); + + CommitSize :=md_up_page(size); + SectionOffset:=offset and (not (MD_ALLOC_GRANULARITY-1)); + ViewSize :=CommitSize; + + Result:=NtMapViewOfSection(hSection, + NtCurrentProcess, + @base, + 0, + CommitSize, + @SectionOffset, + @ViewSize, + ViewUnmap, + 0 {MEM_COMMIT}, + prot + ); + + NtClose(hSection); +end; + +function md_file_unmap(base:Pointer;size:QWORD):Integer; +begin + base:=md_alloc_page(base); + + Result:=NtUnmapViewOfSection(NtCurrentProcess,@base); +end; + // procedure md_cacheflush(addr:Pointer;nbytes,cache:Integer); diff --git a/sys/md/md_vnops.pas b/sys/md/md_vnops.pas index 9bee3b75..76f4c89b 100644 --- a/sys/md/md_vnops.pas +++ b/sys/md/md_vnops.pas @@ -1313,6 +1313,8 @@ begin Result:=md_update_dirent(THandle(vp^.v_un),de,nil); + vnode_pager_setsize(vp, de^.ufs_size); + sx_xunlock(@de^.ufs_md_lock); if (Result<>0) then Exit; @@ -2403,19 +2405,6 @@ begin Dec(uio^.uio_iovcnt); end; - if (Result=0) and (uio^.uio_rw=UIO_WRITE) then - begin - if not locked then - begin - sx_xlock(@de^.ufs_md_lock); - end; - - md_update_dirent(F,de,nil); - - vnode_pager_setsize(vp, de^.ufs_size); - - sx_xunlock(@de^.ufs_md_lock); - end else if locked then begin sx_xunlock(@de^.ufs_md_lock); diff --git a/sys/md/vm_pmap.pas b/sys/md/vm_pmap.pas index e3a802be..3342f828 100644 --- a/sys/md/vm_pmap.pas +++ b/sys/md/vm_pmap.pas @@ -8,7 +8,9 @@ interface uses vm, vmparam, - sys_vm_object; + sys_vm_object, + vm_file, + vnode; const PAGE_MAP_COUNT =(QWORD(VM_MAXUSER_ADDRESS) shr PAGE_SHIFT); @@ -329,6 +331,40 @@ const MD_PROT_RW //XWR ); +function get_vnode_handle(obj:vm_object_t):THandle; +var + vp:p_vnode; +begin + Result:=0; + + vp:=obj^.handle; + + if (vp<>nil) then + begin + VI_LOCK(vp); + + Result:=THandle(vp^.v_un); + + VI_UNLOCK(vp); + end; +end; + +function vm_file_map_fixed(map :p_vm_file_map; + offset:vm_ooffset_t; + start :vm_offset_t; + __end :vm_offset_t; + base :Pointer; + size :QWORD):Integer; +var + obj:p_vm_file_obj; +begin + vm_file_map_delete(map,start,__end); + + obj:=vm_file_obj_allocate(base,size,@md_file_unmap); + + Result:=vm_file_map_insert(map,obj,offset,start,__end); +end; + { * Maps a sequence of resident pages belonging to the same object. * The sequence begins with the given page m_start. This page is @@ -350,8 +386,10 @@ procedure pmap_enter_object(pmap :pmap_t; label _default; var + fd:THandle; base:Pointer; size:QWORD; + delta:QWORD; r:Integer; begin Writeln('pmap_enter_object:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prot,2)); @@ -371,12 +409,12 @@ begin end; OBJT_DEVICE: begin - if (obj^.map_base=nil) then + if (obj^.un_pager.map_base=nil) then begin goto _default; end; - base:=obj^.map_base+trunc_page(offset); + base:=obj^.un_pager.map_base+trunc_page(offset); size:=trunc_page(__end-start); if ((obj^.flags and OBJ_DMEM_EXT)<>0) then @@ -386,6 +424,43 @@ begin r:=md_enter(base,size,MD_PROT_RWX); end; end; + OBJT_VNODE: + begin + VM_OBJECT_LOCK(obj); + + fd:=get_vnode_handle(obj); + + if (fd<>0) then + begin + + delta :=offset and (MD_ALLOC_GRANULARITY-1); + offset:=offset and (not (MD_ALLOC_GRANULARITY-1)); + + size:=delta+offset+(__end-start); + + if (size>obj^.un_pager.vnp.vnp_size) then + begin + size:=obj^.un_pager.vnp.vnp_size; + end; + size:=size-offset; + + base:=nil; + r:=md_file_mmap(fd,base,offset,size,wprots[prot and VM_RWX]); + + if (r=0) then + begin + r:=vm_file_map_fixed(@obj^.un_pager.vnp.file_map, + delta, + start, + __end, + base, + size); + end; + + end; + + VM_OBJECT_UNLOCK(obj); + end; else begin Writeln('TODO:',vm_object_type(obj)); @@ -489,12 +564,12 @@ begin end; OBJT_DEVICE: begin - if (obj^.map_base=nil) then + if (obj^.un_pager.map_base=nil) then begin goto _default; end; - base:=obj^.map_base+trunc_page(offset); + base:=obj^.un_pager.map_base+trunc_page(offset); size:=trunc_page(__end-start); if ((obj^.flags and OBJ_DMEM_EXT)<>0) then @@ -551,7 +626,7 @@ begin end; OBJT_DEVICE: begin - if (obj^.map_base=nil) then + if (obj^.un_pager.map_base=nil) then begin goto _default; end; @@ -608,12 +683,12 @@ begin end; OBJT_DEVICE: begin - if (obj^.map_base=nil) then + if (obj^.un_pager.map_base=nil) then begin goto _default; end; - base:=obj^.map_base+trunc_page(offset); + base:=obj^.un_pager.map_base+trunc_page(offset); size:=trunc_page(__end-start); if ((obj^.flags and OBJ_DMEM_EXT)<>0) then diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr index ce5b182a..6f40a337 100644 --- a/sys/test/project1.lpr +++ b/sys/test/project1.lpr @@ -375,22 +375,18 @@ begin //fs guest host err:=vfs_mount_mkdir('ufs','/app0' ,'/' ,nil,0); err:=vfs_mount_mkdir('ufs','/system','/system',nil,0); - - err:=vfs_unmount_rmdir('/app0' ,0); - err:=vfs_unmount_rmdir('/system',0); - - err:=vfs_mount_mkdir('ufs','/app0' ,'/' ,nil,0); - err:=vfs_mount_mkdir('ufs','/system','/system',nil,0); + err:=vfs_mount_mkdir('ufs','/data' ,'/data' ,nil,0); //argv0:='/app0/basic-sample_debug.elf'; //argv0:='/app0/simple.elf'; - //argv0:='/app0/videoout_basic.elf'; - argv0:='/app0/videoout_cursor.elf'; + argv0:='/app0/videoout_basic.elf'; + //argv0:='/app0/videoout_basic.bin'; + //argv0:='/app0/videoout_cursor.elf'; //argv0:='/app0/scene2.bin'; //argv0:='/app0/basic_quad_debug.elf'; - //argv0:='/app0/hello_world.bin'; + argv0:='/app0/hello_world8.bin'; err:=_execve(argv0,@argv0,nil); end; diff --git a/sys/vfs/vfs_subr.pas b/sys/vfs/vfs_subr.pas index 53ef239c..eb81303b 100644 --- a/sys/vfs/vfs_subr.pas +++ b/sys/vfs/vfs_subr.pas @@ -1046,13 +1046,8 @@ begin Exit(0); end; - if (vp^.v_object<>nil) then - begin - vm_object_deallocate(vp^.v_object); - vp^.v_object:=nil; - end; - //Exit(bufobj_invalbuf(@vp^.v_bufobj, flags, slpflag, slptimeo)); + Result:=0; end; diff --git a/sys/vm/sys_vm_object.pas b/sys/vm/sys_vm_object.pas index 11eed5c1..ce046343 100644 --- a/sys/vm/sys_vm_object.pas +++ b/sys/vm/sys_vm_object.pas @@ -8,6 +8,8 @@ interface uses mqueue, vm, + vmparam, + vm_file, kern_mtx; type @@ -30,25 +32,27 @@ type p_vm_object_t=^vm_object_t; vm_object_t=^t_vm_object; - t_vm_object=packed 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 - handle :Pointer; - paging_in_progress:Integer; - map_base :Pointer; - un_pager:packed record - vnp:packed record + 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; + handle :Pointer; + un_pager :record + map_base:Pointer; + vnp:record + file_map:vm_file_map; vnp_size:QWORD; writemappings:vm_ooffset_t; end; - physhm:packed record - mtype:Byte; + physhm:record + map_base:Pointer; + mtype :Byte; end; end; end; @@ -180,15 +184,29 @@ begin Result^.generation:=1; Result^.ref_count :=1; - if (t=OBJT_DEFAULT) then - begin - Result^.flags:=OBJ_ONEMAPPING; + case t of + OBJT_DEFAULT: + begin + Result^.flags:=OBJ_ONEMAPPING; + end; + OBJT_VNODE: + begin + vm_file_map_init(@Result^.un_pager.vnp.file_map,0,VM_MAXUSER_ADDRESS); + end; + else; end; + end; procedure vm_object_destroy(obj:vm_object_t); begin mtx_destroy(obj^.mtx); + + if (obj^.otype=OBJT_VNODE) then + begin + vm_file_map_free(@obj^.un_pager.vnp.file_map); + end; + FreeMem(obj); end; @@ -216,7 +234,7 @@ begin if (obj=nil) then Exit; VM_OBJECT_LOCK_ASSERT(obj); - obj^.paging_in_progress:=obj^.paging_in_progress+i; + obj^.pip:=obj^.pip+i; end; procedure vm_object_pip_subtract(obj:vm_object_t;i:word); @@ -224,7 +242,7 @@ begin if (obj=nil) then Exit; VM_OBJECT_LOCK_ASSERT(obj); - obj^.paging_in_progress:=obj^.paging_in_progress-i; + obj^.pip:=obj^.pip-i; end; function vm_object_type(obj:vm_object_t):obj_type; diff --git a/sys/vm/vm_file.pas b/sys/vm/vm_file.pas new file mode 100644 index 00000000..a01b79b1 --- /dev/null +++ b/sys/vm/vm_file.pas @@ -0,0 +1,444 @@ +unit vm_file; + +{$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} + +interface + +uses + vm, + vmparam; + +type + t_uncb=function(base:Pointer;size:QWORD):Integer; + + p_vm_file_obj=^vm_file_obj; + vm_file_obj=packed record + base:Pointer; + size:QWORD; + refs:QWORD; + uncb:t_uncb; + end; + + pp_vm_file_entry=^p_vm_file_entry; + p_vm_file_entry=^vm_file_entry; + vm_file_entry=packed record + prev :p_vm_file_entry; + next :p_vm_file_entry; + left :p_vm_file_entry; + right :p_vm_file_entry; + start :QWORD; + __end :QWORD; + offset:QWORD; + obj :p_vm_file_obj; + end; + + p_vm_file_map=^vm_file_map; + vm_file_map=packed object + header :vm_file_entry; + root :p_vm_file_entry; + nentries:DWORD; + pages :DWORD; + property min_offset:QWORD read header.start write header.start; + property max_offset:QWORD read header.__end write header.__end; + end; + +function vm_file_obj_allocate (base:Pointer;size:QWORD;uncb:t_uncb):p_vm_file_obj; +procedure vm_file_obj_destroy (obj:p_vm_file_obj); +procedure vm_file_obj_reference (obj:p_vm_file_obj); +procedure vm_file_obj_deallocate(obj:p_vm_file_obj); + +procedure vm_file_map_init(map:p_vm_file_map;min,max:QWORD); +procedure vm_file_map_free(map:p_vm_file_map); + +function vm_file_map_lookup_entry( + map :p_vm_file_map; + address:QWORD; + entry :pp_vm_file_entry):Boolean; + +function vm_file_map_insert( + map :p_vm_file_map; + obj :p_vm_file_obj; + offset:QWORD; + start :QWORD; + __end :QWORD):Integer; + +function vm_file_map_delete(map:p_vm_file_map; + start:QWORD; + __end:QWORD):Integer; + +implementation + +function OFF_TO_IDX(x:QWORD):DWORD; inline; +begin + Result:=QWORD(x) shr PAGE_SHIFT; +end; + +function vm_file_obj_allocate(base:Pointer;size:QWORD;uncb:t_uncb):p_vm_file_obj; +begin + Result:=AllocMem(SizeOf(vm_file_obj)); + + Result^.base:=base; + Result^.size:=size; + Result^.refs:=1; + Result^.uncb:=uncb; +end; + +procedure vm_file_obj_destroy(obj:p_vm_file_obj); +begin + if (obj^.uncb<>nil) then + begin + obj^.uncb(obj^.base,obj^.size); + end; + + FreeMem(obj); +end; + +procedure vm_file_obj_reference(obj:p_vm_file_obj); +begin + if (obj=nil) then Exit; + + System.InterlockedIncrement64(obj^.refs); +end; + +procedure vm_file_obj_deallocate(obj:p_vm_file_obj); +begin + if (obj=nil) then Exit; + + if (System.InterlockedDecrement64(obj^.refs)=0) then + begin + vm_file_obj_destroy(obj); + end; +end; + +procedure vm_file_map_init(map:p_vm_file_map;min,max:QWORD); +begin + map^.header.next:=@map^.header; + map^.header.prev:=@map^.header; + map^.min_offset :=min; + map^.max_offset :=max; + map^.root :=nil; + map^.nentries :=0; + map^.pages :=0; +end; + +procedure vm_file_map_free(map:p_vm_file_map); +begin + vm_file_map_delete(map,map^.min_offset,map^.max_offset); +end; + +procedure vm_file_entry_dispose(map:p_vm_file_map;entry:p_vm_file_entry); inline; +begin + vm_file_obj_deallocate(entry^.obj); + FreeMem(entry); +end; + +function vm_file_entry_create(map:p_vm_file_map):p_vm_file_entry; +var + new_entry:p_vm_file_entry; +begin + new_entry:=AllocMem(SizeOf(vm_file_entry)); + Assert((new_entry<>nil),'vm_file_entry_create: kernel resources exhausted'); + Result:=new_entry; +end; + +function vm_file_entry_splay(addr:QWORD;root:p_vm_file_entry):p_vm_file_entry; +var + llist,rlist:p_vm_file_entry; + ltree,rtree:p_vm_file_entry; + y :p_vm_file_entry; +begin + if (root=nil) then Exit(root); + + llist:=nil; + rlist:=nil; + repeat + if (addrnil) then + begin + root^.left:=y^.right; + y^.right:=root; + root:=y^.left; + y^.left:=rlist; + rlist:=y; + end else + begin + root^.left:=rlist; + rlist:=root; + root:=y; + end; + end else + if (addr>=root^.__end) then + begin + y:=root^.right; + if (y=nil) then break; + if (addr>=y^.__end) and (y^.right<>nil) then + begin + root^.right:=y^.left; + y^.left:=root; + root:=y^.right; + y^.right:=llist; + llist:=y; + end else + begin + root^.right:=llist; + llist:=root; + root:=y; + end; + end else + begin + break; + end; + until false; + + ltree:=root^.left; + while (llist<>nil) do + begin + y:=llist^.right; + llist^.right:=ltree; + ltree:=llist; + llist:=y; + end; + + rtree:=root^.right; + while (rlist<>nil) do + begin + y:=rlist^.left; + rlist^.left:=rtree; + rtree:=rlist; + rlist:=y; + end; + + root^.left:=ltree; + root^.right:=rtree; + + Result:=(root); +end; + +procedure vm_file_map_entry_link( + map :p_vm_file_map; + after_where:p_vm_file_entry; + entry :p_vm_file_entry); +begin + Inc(map^.nentries); + + entry^.prev:=after_where; + entry^.next:=after_where^.next; + entry^.next^.prev:=entry; + after_where^.next:=entry; + + if (after_where<>@map^.header) then + begin + if (after_where<>map^.root) then + begin + vm_file_entry_splay(after_where^.start, map^.root); + end; + entry^.right:=after_where^.right; + entry^.left:=after_where; + after_where^.right:=nil; + end else + begin + entry^.right:=map^.root; + entry^.left:=nil; + end; + map^.root:=entry; +end; + +procedure vm_file_map_entry_unlink( + map :p_vm_file_map; + entry:p_vm_file_entry); +var + next,prev,root:p_vm_file_entry; +begin + if (entry<>map^.root) then + begin + vm_file_entry_splay(entry^.start, map^.root); + end; + if (entry^.left=nil) then + begin + root:=entry^.right; + end else + begin + root:=vm_file_entry_splay(entry^.start, entry^.left); + root^.right:=entry^.right; + end; + map^.root:=root; + + prev:=entry^.prev; + next:=entry^.next; + next^.prev:=prev; + prev^.next:=next; + Dec(map^.nentries); +end; + +function vm_file_map_lookup_entry( + map :p_vm_file_map; + address:QWORD; + entry :pp_vm_file_entry):Boolean; +var + cur:p_vm_file_entry; +begin + cur:=map^.root; + if (cur=nil) then + begin + entry^:=@map^.header; + end else + if (address>=cur^.start) and (cur^.__end>address) then + begin + entry^:=cur; + Exit(TRUE); + end else + begin + cur:=vm_file_entry_splay(address,cur); + map^.root:=cur; + + if (address>=cur^.start) then + begin + entry^:=cur; + if (cur^.__end>address) then + begin + Exit(TRUE); + end; + end else + begin + entry^:=cur^.prev; + end; + end; + Result:=(FALSE); +end; + +function vm_file_map_insert( + map :p_vm_file_map; + obj :p_vm_file_obj; + offset:QWORD; + start :QWORD; + __end :QWORD):Integer; +var + new_entry :p_vm_file_entry; + prev_entry:p_vm_file_entry; + temp_entry:p_vm_file_entry; +begin + if (start>=__end) then + begin + Exit(KERN_INVALID_ADDRESS); + end; + + if vm_file_map_lookup_entry(map,start,@temp_entry) then + begin + Exit(KERN_NO_SPACE); + end; + + prev_entry:=temp_entry; + + if (prev_entry^.next<>@map^.header) and + (prev_entry^.next^.start<__end) then + begin + Exit(KERN_NO_SPACE); + end; + + new_entry:=vm_file_entry_create(map); + new_entry^.start:=start; + new_entry^.__end:=__end; + + new_entry^.offset:=offset; + new_entry^.obj :=obj; + + vm_file_map_entry_link(map, prev_entry, new_entry); + map^.pages:=map^.pages+OFF_TO_IDX(new_entry^.__end - new_entry^.start); +end; + +procedure vm_file_map_entry_delete(map:p_vm_file_map;entry:p_vm_file_entry); +begin + vm_file_map_entry_unlink(map, entry); + + map^.pages:=map^.pages-OFF_TO_IDX(entry^.__end - entry^.start); + + vm_file_entry_dispose(map,entry); +end; + +procedure _vm_map_clip_start(map:p_vm_file_map;entry:p_vm_file_entry;start:QWORD); +var + new_entry:p_vm_file_entry; +begin + new_entry:=vm_file_entry_create(map); + new_entry^:=entry^; + + new_entry^.__end:=start; + entry^.offset:=entry^.offset + (start - entry^.start); + entry^.start:=start; + + vm_file_map_entry_link(map, entry^.prev, new_entry); + + vm_file_obj_reference(new_entry^.obj); +end; + +procedure vm_map_clip_start(map:p_vm_file_map;entry:p_vm_file_entry;start:QWORD); +begin + if (start>entry^.start) then + begin + _vm_map_clip_start(map,entry,start); + end; +end; + +procedure _vm_map_clip_end(map:p_vm_file_map;entry:p_vm_file_entry;__end:QWORD); +var + new_entry:p_vm_file_entry; +begin + new_entry:=vm_file_entry_create(map); + new_entry^:=entry^; + + new_entry^.start:=__end; + entry^.__end:=__end; + new_entry^.offset:=new_entry^.offset + (__end - entry^.start); + + vm_file_map_entry_link(map, entry, new_entry); + + vm_file_obj_reference(new_entry^.obj); +end; + +procedure vm_map_clip_end(map:p_vm_file_map;entry:p_vm_file_entry;__end:QWORD); +begin + if (__end@map^.header) and (entry^.start<__end) do + begin + vm_map_clip_end(map, entry, __end); + next:=entry^.next; + vm_file_map_entry_delete(map, entry); + entry:=next; + end; + Result:=(KERN_SUCCESS); +end; + +end. + diff --git a/sys/vm/vm_map.pas b/sys/vm/vm_map.pas index 021063fa..8682166a 100644 --- a/sys/vm/vm_map.pas +++ b/sys/vm/vm_map.pas @@ -1136,8 +1136,6 @@ charged: new_entry^.entry_id:=map^.entry_id; Inc(map^.entry_id); - vm_object_reference(obj); - Assert(not ENTRY_CHARGED(new_entry),'OVERCOMMIT: vm_map_insert leaks vm_map %p", new_entry'); { @@ -2070,7 +2068,7 @@ var current:vm_map_entry_t; entry :vm_map_entry_t; size :vm_size_t; - vm_obj :vm_object_t; + obj :vm_object_t; offset :vm_ooffset_t; last_timestamp:DWORD; failed:Boolean; @@ -2145,21 +2143,21 @@ begin begin size:=tsize; end; - vm_obj:=tentry^.vm_obj; + obj:=tentry^.vm_obj; offset:=tentry^.offset + (offset - tentry^.start); vm_map_unlock(smap); end else begin - vm_obj:=current^.vm_obj; + obj:=current^.vm_obj; end; - vm_object_reference(vm_obj); + vm_object_reference(obj); last_timestamp:=map^.timestamp; vm_map_unlock(map); //if (not vm_object_sync(_object, offset, size, syncio, invalidate)) then // failed:=TRUE; start:=start+size; - vm_object_deallocate(vm_obj); + vm_object_deallocate(obj); vm_map_lock(map); if (last_timestamp=map^.timestamp) or (not vm_map_lookup_entry(map, start, @current)) then diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas index 24e043a7..c23feee1 100644 --- a/sys/vm/vm_mmap.pas +++ b/sys/vm/vm_mmap.pas @@ -511,7 +511,7 @@ begin if (rv=KERN_SUCCESS) then begin - // + //vm_map_wire end else begin if (writecounted) then @@ -521,6 +521,7 @@ begin vm_object_deallocate(obj); end; + Exit(vm_mmap_to_errno(rv)); end; diff --git a/sys/vm/vm_object.pas b/sys/vm/vm_object.pas index 0778146a..237fabeb 100644 --- a/sys/vm/vm_object.pas +++ b/sys/vm/vm_object.pas @@ -91,7 +91,7 @@ begin } vm_object_pip_wait(obj, 'objtrm'); - Assert(obj^.paging_in_progress=0,'vm_object_terminate: pageout in progress'); + Assert(obj^.pip=0,'vm_object_terminate: pageout in progress'); vm_object_patch_remove(obj,0,0); @@ -235,8 +235,8 @@ begin if (obj=nil) then Exit; VM_OBJECT_LOCK_ASSERT(obj); - Dec(obj^.paging_in_progress); - if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.paging_in_progress=0) then + Dec(obj^.pip); + if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.pip=0) then begin vm_object_clear_flag(obj, OBJ_PIPWNT); wakeup(obj); @@ -248,8 +248,8 @@ begin if (obj=nil) then Exit; VM_OBJECT_LOCK_ASSERT(obj); - Dec(obj^.paging_in_progress,i); - if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.paging_in_progress=0) then + Dec(obj^.pip,i); + if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.pip=0) then begin vm_object_clear_flag(obj, OBJ_PIPWNT); wakeup(obj); @@ -261,7 +261,7 @@ begin if (obj=nil) then Exit; VM_OBJECT_LOCK_ASSERT(obj); - while (obj^.paging_in_progress<>0) do + while (obj^.pip<>0) do begin obj^.flags:=obj^.flags or OBJ_PIPWNT; msleep(obj, VM_OBJECT_MTX(obj), PVM, waitid, 0); diff --git a/sys/vm/vnode_pager.pas b/sys/vm/vnode_pager.pas index 2070e21b..b42ad446 100644 --- a/sys/vm/vnode_pager.pas +++ b/sys/vm/vnode_pager.pas @@ -187,11 +187,11 @@ begin * Dereference the reference we just created. This assumes * that the obj is associated with the vp. } - //VM_OBJECT_LOCK(obj); - // Dec(obj^.ref_count); - //VM_OBJECT_UNLOCK(obj); + VM_OBJECT_LOCK(obj); + Dec(obj^.ref_count); + VM_OBJECT_UNLOCK(obj); - //vrele(vp); + vrele(vp); Assert(vp^.v_object<>nil, 'vnode_create_vobject: nil obj');