From ecf4f7d7bced46d8349a8131a5b10453ccb5230c Mon Sep 17 00:00:00 2001 From: Pavel <68122101+red-prig@users.noreply.github.com> Date: Sun, 18 Feb 2024 02:08:40 +0300 Subject: [PATCH] + --- fpPS4.lpi | 8 + gui/game_run.pas | 30 ++- gui/main.pas | 48 ++-- sys/dev/dev_dce.pas | 42 ++-- sys/dev/dev_dipsw.pas | 2 +- sys/dev/dev_dmem.pas | 2 +- sys/dev/dev_gc.pas | 7 +- sys/dev/dev_null.pas | 2 +- sys/dev/dev_rng.pas | 2 +- sys/dev/dev_tty.pas | 2 +- sys/dev/devfs_int.pas | 235 ++++++++++++++++++ sys/dev/display_interface.pas | 9 +- sys/fs/devfs/devfs.pas | 261 +++----------------- sys/fs/devfs/devfs_devs.pas | 6 +- sys/fs/devfs/devfs_rule.pas | 13 +- sys/fs/devfs/devfs_vfsops.pas | 11 +- sys/fs/devfs/devfs_vnops.pas | 16 +- sys/host_ipc.pas | 167 ++++++++++--- sys/kern/kern_blockpool.pas | 2 +- sys/kern/kern_event.pas | 337 +++++++++++++++++-------- sys/kern/kern_exec.pas | 1 - sys/kern/kern_exit.pas | 5 +- sys/kern/kern_proc.pas | 39 --- sys/kern/uipc_syscalls.pas | 2 +- sys/md/md_exception.pas | 7 +- sys/md/md_host_ipc.pas | 50 ++-- sys/md/md_systm.pas | 79 +++--- sys/sys_conf.pas | 450 ++++++++++++++++++++++++++++++++++ sys/sys_event.pas | 23 ++ sys/sys_eventvar.pas | 2 + sys/sys_sysinit.pas | 5 +- sys/vfs/kern_conf.pas | 431 ++------------------------------ sys/vfs/kern_descrip.pas | 4 +- sys/vfs/vfs_subr.pas | 2 +- sys/vm/device_pager.pas | 2 +- sys/vm/vm_mmap.pas | 2 +- 36 files changed, 1337 insertions(+), 969 deletions(-) create mode 100644 sys/dev/devfs_int.pas create mode 100644 sys/sys_conf.pas diff --git a/fpPS4.lpi b/fpPS4.lpi index a1642674..1fe6b3da 100644 --- a/fpPS4.lpi +++ b/fpPS4.lpi @@ -846,6 +846,14 @@ + + + + + + + + diff --git a/gui/game_run.pas b/gui/game_run.pas index 5763c1fb..3f307af4 100644 --- a/gui/game_run.pas +++ b/gui/game_run.pas @@ -9,6 +9,7 @@ uses Classes, SysUtils, kern_thr, + md_sleep, md_pipe, host_ipc, md_host_ipc, @@ -54,6 +55,8 @@ uses sys_tty, md_exception, //<- install custom + sys_event, + kern_proc, md_systm, @@ -106,6 +109,8 @@ begin //init all sys_init; + kern_ipc.thread_new; + PROC_INIT_HOST_IPC(kern_ipc); Writeln(Item.FGameInfo.Exec); @@ -204,7 +209,7 @@ begin r:=kthread_add(@prepare,Item,@td,'[main]'); Assert(r=0); - sleep(-1); + msleep_td(0); end; function run_item(const cfg:TGameRunConfig;Item:TGameItem):TGameProcess; @@ -213,6 +218,10 @@ var kern2mgui:array[0..1] of THandle; + fork_info:t_fork_proc; + + kev:t_kevent; + p_mgui_ipc:THostIpcPipeMGUI; s_kern_ipc:THostIpcSimpleKERN; @@ -228,6 +237,8 @@ begin SetStdHandle(STD_OUTPUT_HANDLE,cfg.hOutput); SetStdHandle(STD_ERROR_HANDLE ,cfg.hError ); + fork_info:=Default(t_fork_proc); + if cfg.fork_proc then begin Result:=TGameProcessPipe.Create; @@ -252,9 +263,11 @@ begin Item.Serialize(mem); + r:=md_fork_process(@fork_process,mem.Memory,mem.Size,fork_info); + with TGameProcessPipe(Result) do begin - FProcess:=md_fork_process(@fork_process,mem.Memory,mem.Size); + FProcess:=fork_info.hProcess; end; mem.Free; @@ -278,10 +291,23 @@ begin Ftd:=nil; r:=kthread_add(@prepare,Item,@Ftd,'[main]'); + + fork_info.fork_pid:=GetProcessID; end; end; + Result.g_ipc.thread_new; + + kev.ident :=fork_info.fork_pid; + kev.filter:=EVFILT_PROC; + kev.flags :=EV_ADD; + kev.fflags:=NOTE_EXIT or NOTE_EXEC; + kev.data :=0; + kev.udata :=nil; + + Result.g_ipc.kevent(@kev,1); + runing:=True; end; diff --git a/gui/main.pas b/gui/main.pas index f2407cbe..ef036fc7 100644 --- a/gui/main.pas +++ b/gui/main.pas @@ -78,8 +78,7 @@ uses TypInfo, Rtti, - evbuffer, - evpoll; + sys_event; // @@ -123,28 +122,49 @@ type TGuiIpcHandler=class(THostIpcHandler) Form:TfrmMain; function OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint; override; + function OnKevent(kev:p_kevent;count:Integer):Ptruint; end; function TGuiIpcHandler.OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint; begin Result:=0; case mtype of - iKNOTE: - with PHostIpcKnote(buf)^ do - begin - ShowMessage('iKNOTE pid:'+IntToStr(pid)+ - ' filter:'+IntToStr(filter)+ - ' hint:'+HexStr(hint,16) - ); - end; - - + iKEV_EVENT:Result:=OnKevent(buf,mlen div sizeof(t_kevent)); else; ShowMessage(GetEnumName(TypeInfo(mtype),ord(mtype))); end; end; -//PHostIpcKnote +function TGuiIpcHandler.OnKevent(kev:p_kevent;count:Integer):Ptruint; +var + i:Integer; +begin + Result:=0; + + i:=0; + while (i<>count) do + begin + case kev[i].filter of + EVFILT_PROC: + begin + if ((kev[i].fflags and NOTE_EXIT)<>0) then + begin + ShowMessage('NOTE_EXIT pid:'+IntToStr(kev[i].ident)); + end; + if ((kev[i].fflags and NOTE_EXEC)<>0) then + begin + ShowMessage('NOTE_EXEC pid:'+IntToStr(kev[i].ident)); + end; + end; + + else; + end; + + Inc(i); + end; + +end; + var IpcHandler:TGuiIpcHandler; @@ -409,7 +429,7 @@ begin cfg.hOutput:=FAddHandle; cfg.hError :=FAddHandle; - cfg.fork_proc:=False; + cfg.fork_proc:=True; GameProcess:=run_item(cfg,Item); end; diff --git a/sys/dev/dev_dce.pas b/sys/dev/dev_dce.pas index 946c4477..2e9299c1 100644 --- a/sys/dev/dev_dce.pas +++ b/sys/dev/dev_dce.pas @@ -9,7 +9,7 @@ uses sysutils, vm, vmparam, - kern_conf, + sys_conf, sys_event, time, kern_mtx, @@ -38,7 +38,6 @@ uses subr_backtrace, sys_vm_object, vm_pager, - kern_event, md_time, kern_proc, kern_timeout; @@ -755,10 +754,13 @@ type rout :PQWORD; //extraout of result end; +var + f_eop_count:Integer=0; + Function dce_submit_flip(dev:p_cdev;data:p_submit_flip_args):Integer; var submit:t_submit_flip; - eop_val:PQWORD; + submit_eop:QWORD; ures:QWORD; begin Result:=0; @@ -766,24 +768,12 @@ begin if (data^.canary<>$a5a5) then Exit(EINVAL); if (data^.bufferIndex>15) then Exit(EINVAL); - if (data^.eop_nz>1) then Exit(EINVAL); submit.bufferIndex:=data^.bufferIndex; submit.flipMode :=data^.flipMode; submit.flipArg :=data^.flipArg; submit.flipArg2 :=data^.flipArg2; - // count canary - //eop=0x[00000001] [ff] [00] [a5a5] - - if (data^.eop_nz=1) then - begin - eop_val:=data^.eop_val; - end else - begin - eop_val:=nil; - end; - mtx_lock(dce_mtx); if (dce_handle=nil) then @@ -791,7 +781,22 @@ begin Result:=EINVAL; end else begin - Result:=dce_handle.SubmitFlip(@submit,eop_val); + + if (data^.eop_nz=1) then + begin + // count canary + //eop=0x[00000001] [ff] [00] [a5a5] + + f_eop_count:=f_eop_count+1; + + submit_eop:=(QWORD(f_eop_count) shl 32) or QWORD($ff00a5a5); + + Result:=dce_handle.SubmitFlipEop(@submit,submit_eop); + end else + begin + Result:=dce_handle.SubmitFlip(@submit); + end; + end; mtx_unlock(dce_mtx); @@ -805,6 +810,11 @@ begin flipArg:=data^.flipArg; + if (data^.eop_nz=1) then + begin + Result:=copyout(@submit_eop,data^.eop_val,SizeOf(QWORD)); + end; + if (data^.rout<>nil) then begin ures:=Result; diff --git a/sys/dev/dev_dipsw.pas b/sys/dev/dev_dipsw.pas index 866565e2..cbcb0e54 100644 --- a/sys/dev/dev_dipsw.pas +++ b/sys/dev/dev_dipsw.pas @@ -6,7 +6,7 @@ unit dev_dipsw; interface uses - kern_conf; + sys_conf; procedure dipsw_init(); diff --git a/sys/dev/dev_dmem.pas b/sys/dev/dev_dmem.pas index 7ef9300b..ce5719c1 100644 --- a/sys/dev/dev_dmem.pas +++ b/sys/dev/dev_dmem.pas @@ -6,7 +6,7 @@ unit dev_dmem; interface uses - kern_conf; + sys_conf; procedure dmemdev_init(); diff --git a/sys/dev/dev_gc.pas b/sys/dev/dev_gc.pas index 2605f4e1..c2806a6d 100644 --- a/sys/dev/dev_gc.pas +++ b/sys/dev/dev_gc.pas @@ -6,7 +6,7 @@ unit dev_gc; interface uses - kern_conf; + sys_conf; procedure gc_initialize(); @@ -16,7 +16,6 @@ uses errno, kern_mtx, sys_event, - kern_event, kern_authinfo, vm, vmparam, @@ -265,6 +264,8 @@ var cap:Boolean; unk:Integer; begin + Result:=0; + event_id:=Byte(kn^.kn_data); cap:=sceSblACMgrHasUseHp3dPipeCapability(@g_authinfo); @@ -333,7 +334,7 @@ begin begin Result:=1; - event_id:=PByte(@kn^.kn_kevent.data)[1]; + event_id:=Byte(kn^.kn_kevent.data shr 8); kn^.kn_kevent.data:=(hint and QWORD($ffffffffffff00ff)) or (QWORD(event_id) shl 8); diff --git a/sys/dev/dev_null.pas b/sys/dev/dev_null.pas index 67e78e16..1e44128f 100644 --- a/sys/dev/dev_null.pas +++ b/sys/dev/dev_null.pas @@ -6,7 +6,7 @@ unit dev_null; interface uses - kern_conf; + sys_conf; const ZERO_REGION_SIZE=(2 * 1024 * 1024); // 2MB diff --git a/sys/dev/dev_rng.pas b/sys/dev/dev_rng.pas index 3385c2f4..ea927c0c 100644 --- a/sys/dev/dev_rng.pas +++ b/sys/dev/dev_rng.pas @@ -6,7 +6,7 @@ unit dev_rng; interface uses - kern_conf; + sys_conf; procedure rng_init(); diff --git a/sys/dev/dev_tty.pas b/sys/dev/dev_tty.pas index c535e963..3052c4a7 100644 --- a/sys/dev/dev_tty.pas +++ b/sys/dev/dev_tty.pas @@ -9,7 +9,7 @@ uses sysutils, vselinfo, kern_thr, - kern_conf, + sys_conf, sys_tty; var diff --git a/sys/dev/devfs_int.pas b/sys/dev/devfs_int.pas new file mode 100644 index 00000000..8ff221db --- /dev/null +++ b/sys/dev/devfs_int.pas @@ -0,0 +1,235 @@ +unit devfs_int; + +{$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} + +interface + +uses + mqueue, + time, + vfile, + vdirent, + vnode, + vmount, + sys_conf, + kern_mtx, + kern_sx; + +const + DEVFS_MAGIC=$db0a087a; + +{ + * Identifiers. The ruleset and rule numbers are 16-bit values. The + * "rule ID" is a combination of the ruleset and rule number; it + * should be able to univocally describe a rule in the system. In + * this implementation, the upper 16 bits of the rule ID is the + * ruleset number; the lower 16 bits, the rule number within the + * aforementioned ruleset. + } +type + p_devfs_rnum=^devfs_rnum; + devfs_rnum=WORD; + + p_devfs_rsnum=^devfs_rsnum; + devfs_rsnum=WORD; + + p_devfs_rid=^devfs_rid; + devfs_rid=DWORD; + + ino_t=Integer; + +const + DRC_DSWFLAGS =$001; + DRC_PATHPTRN =$002; + DEVFS_MAXPTRNLEN=200; + + DRA_BACTS =$001; + DRA_UID =$002; + DRA_GID =$004; + DRA_MODE =$008; + DRA_INCSET=$010; + + DRB_HIDE =$001; { Hide entry (DE_WHITEOUT). } + DRB_UNHIDE=$002; { Unhide entry. } + +{ + * Plain DEVFS rule. This gets shared between kernel and userland + * verbatim, so it shouldn't contain any pointers or other kernel- or + * userland-specific values. + } +type + p_devfs_rule=^t_devfs_rule; + t_devfs_rule=packed record + dr_magic:DWORD; { Magic number. } + dr_id :devfs_rid; { Identifier. } + + { + * Conditions under which this rule should be applied. These + * are ANDed together since OR can be simulated by using + * multiple rules. dr_icond determines which of the other + * variables we should process. + } + dr_icond:Integer; + + dr_dswflags:Integer; { cdevsw flags to match. } + + dr_pathptrn:array[0..DEVFS_MAXPTRNLEN-1] of AnsiChar; { Pattern to match path. } + + { + * Things to change. dr_iacts determines which of the other + * variables we should process. + } + dr_iacts:Integer; + + dr_bacts:Integer; { Boolean (on/off) action. } + + dr_uid :uid_t; + dr_gid :gid_t; + dr_mode :mode_t; + dr_incset:devfs_rsnum; { Included ruleset. } + end; + +const +{ + * Rule-related ioctls. + } + DEVFSIO_RADD =$C0F04400; + DEVFSIO_RDEL =$80044401; + DEVFSIO_RAPPLY =$80F04402; + DEVFSIO_RAPPLYID=$80044403; + DEVFSIO_RGETNEXT=$C0F04404; + + DEVFSIO_SUSE =$8002440A; + DEVFSIO_SAPPLY =$8002440B; + DEVFSIO_SGETNEXT=$C002440C; + +{ XXX: DEVFSIO_RS_GET_INFO for refcount, active if any, etc. } + + DE_WHITEOUT=$01; + DE_DOT =$02; + DE_DOTDOT =$04; + DE_DOOMED =$08; + DE_COVERED =$10; + DE_USER =$20; + + CDP_ACTIVE =(1 shl 0); + CDP_SCHED_DTR=(1 shl 1); + CDP_UNREF_DTR=(1 shl 2); + +type + t_cdpd_dtr=procedure(P:Pointer); + + p_cdev_privdata=^t_cdev_privdata; + t_cdev_privdata=packed record + cdpd_fp :p_file; + cdpd_data:Pointer; + cdpd_dtr :t_cdpd_dtr; + cdpd_list:LIST_ENTRY; //cdev_privdata + end; + + pp_devfs_dirent=^p_devfs_dirent; + p_devfs_dirent=^t_devfs_dirent; + + p_cdev_priv=^t_cdev_priv; + t_cdev_priv=packed record + cdp_c:t_cdev; + cdp_list:TAILQ_ENTRY; //cdev_priv + + cdp_inode:DWORD; + cdp_flags:DWORD; + + cdp_inuse :DWORD; + cdp_maxdirent:DWORD; + + cdp_dirents:pp_devfs_dirent; + cdp_dirent0:p_devfs_dirent; + + cdp_dtr_list:TAILQ_ENTRY; //cdev_priv + + cdp_dtr_cb :t_cdpd_dtr; + cdp_dtr_cb_arg:Pointer; + + cdp_fdpriv:LIST_HEAD; //cdev_privdata + end; + + devfs_dlist_head=TAILQ_HEAD; //devfs_dirent + + t_devfs_dirent=record + de_cdp :p_cdev_priv; + de_inode :Integer; + de_flags :Integer; + de_holdcnt:Integer; + de_dirent :p_dirent; + de_list :TAILQ_ENTRY; + de_dlist :devfs_dlist_head; + de_dir :p_devfs_dirent; + de_links :Integer; + de_mode :mode_t; + de_uid :uid_t; + de_gid :gid_t; + //label *de_label; + de_atime :timespec; + de_mtime :timespec; + de_ctime :timespec; + de_vnode :p_vnode; + de_symlink:PChar; + end; + + p_devfs_mount=^t_devfs_mount; + t_devfs_mount=record + dm_idx :DWORD ; + dm_mount :p_mount ; + dm_rootdir :p_devfs_dirent; + dm_generation:DWORD ; + dm_holdcnt :Integer ; + dm_lock :t_sx ; + dm_ruleset :devfs_rsnum ; + end; + +const + DEVFS_ROOTINO=2; + + DEVFS_DEL_VNLOCKED =$01; + DEVFS_DEL_NORECURSE=$02; + +var + devfs_rule_depth:DWORD=0; + +type + p_dirlistent=^t_dirlistent; + t_dirlistent=record + dir :PChar; + refcnt:Integer; + link :LIST_ENTRY; //dirlistent + end; + +var + devfs_dirlist:LIST_HEAD=(lh_first:nil); //dirlistent + dirlist_mtx :mtx; //MTX_SYSINIT(dirlist_mtx, &dirlist_mtx, "devfs dirlist lock", MTX_DEF); + + devfs_de_interlock:mtx; //MTX_SYSINIT(devfs_de_interlock, @devfs_de_interlock, 'devfs interlock', MTX_DEF); + cdevpriv_mtx :mtx; //MTX_SYSINIT(cdevpriv_mtx, @cdevpriv_mtx, 'cdevpriv lock', MTX_DEF); + clone_drain_lock :t_sx=(n:'clone events drain lock';c:nil;m:0); + + devfs_generation:DWORD=0; + +var + cdevp_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@cdevp_list.tqh_first); + +function devfs_alloc(flags:Integer):p_cdev; external; +function devfs_dev_exists(name:PChar):Integer; external; +procedure devfs_free(cdev:p_cdev); external; +procedure devfs_create(dev:p_cdev); external; +procedure devfs_destroy(dev:p_cdev); external; +procedure devfs_destroy_cdevpriv(p:p_cdev_privdata); external; + +function devfs_dir_find(path:PChar):Integer; external; +procedure devfs_dir_ref_de(dm:p_devfs_mount;de:p_devfs_dirent); external; +procedure devfs_dir_unref_de(dm:p_devfs_mount;de:p_devfs_dirent); external; +function devfs_pathpath(p1,p2:PChar):Integer; external; + +implementation + +end. + diff --git a/sys/dev/display_interface.pas b/sys/dev/display_interface.pas index f1f0c408..72a4d91f 100644 --- a/sys/dev/display_interface.pas +++ b/sys/dev/display_interface.pas @@ -65,7 +65,8 @@ type function SubmitBufferAttribute (attrid:Byte;attr:p_register_buffer_attr):Integer; virtual; function RegisterBuffer (buf:p_register_buffer):Integer; virtual; function UnregisterBuffer (index:Integer):Integer; virtual; - function SubmitFlip (submit:p_submit_flip;eop_val:PQWORD):Integer; virtual; + function SubmitFlip (submit:p_submit_flip):Integer; virtual; + function SubmitFlipEop (submit:p_submit_flip;submit_id:QWORD):Integer; virtual; end; TDisplayInterface=class @@ -118,11 +119,15 @@ begin Result:=0; end; -function TDisplayHandle.SubmitFlip(submit:p_submit_flip;eop_val:PQWORD):Integer; +function TDisplayHandle.SubmitFlip(submit:p_submit_flip):Integer; begin Result:=0; end; +function TDisplayHandle.SubmitFlipEop(submit:p_submit_flip;submit_id:QWORD):Integer; +begin + Result:=0; +end; end. diff --git a/sys/fs/devfs/devfs.pas b/sys/fs/devfs/devfs.pas index 9d22199a..731d9e75 100644 --- a/sys/fs/devfs/devfs.pas +++ b/sys/fs/devfs/devfs.pas @@ -7,196 +7,13 @@ interface uses sysutils, + devfs_int, mqueue, kern_param, - vfile, - vdirent, vnode, vmount, - time, - kern_conf, - kern_mtx, - kern_sx; - -const - DEVFS_MAGIC=$db0a087a; - -{ - * Identifiers. The ruleset and rule numbers are 16-bit values. The - * "rule ID" is a combination of the ruleset and rule number; it - * should be able to univocally describe a rule in the system. In - * this implementation, the upper 16 bits of the rule ID is the - * ruleset number; the lower 16 bits, the rule number within the - * aforementioned ruleset. - } -type - p_devfs_rnum=^devfs_rnum; - devfs_rnum=WORD; - - p_devfs_rsnum=^devfs_rsnum; - devfs_rsnum=WORD; - - p_devfs_rid=^devfs_rid; - devfs_rid=DWORD; - - ino_t=Integer; - -const - DRC_DSWFLAGS =$001; - DRC_PATHPTRN =$002; - DEVFS_MAXPTRNLEN=200; - - DRA_BACTS =$001; - DRA_UID =$002; - DRA_GID =$004; - DRA_MODE =$008; - DRA_INCSET=$010; - - DRB_HIDE =$001; { Hide entry (DE_WHITEOUT). } - DRB_UNHIDE=$002; { Unhide entry. } - -{ - * Plain DEVFS rule. This gets shared between kernel and userland - * verbatim, so it shouldn't contain any pointers or other kernel- or - * userland-specific values. - } -type - p_devfs_rule=^t_devfs_rule; - t_devfs_rule=packed record - dr_magic:DWORD; { Magic number. } - dr_id :devfs_rid; { Identifier. } - - { - * Conditions under which this rule should be applied. These - * are ANDed together since OR can be simulated by using - * multiple rules. dr_icond determines which of the other - * variables we should process. - } - dr_icond:Integer; - - dr_dswflags:Integer; { cdevsw flags to match. } - - dr_pathptrn:array[0..DEVFS_MAXPTRNLEN-1] of AnsiChar; { Pattern to match path. } - - { - * Things to change. dr_iacts determines which of the other - * variables we should process. - } - dr_iacts:Integer; - - dr_bacts:Integer; { Boolean (on/off) action. } - - dr_uid :uid_t; - dr_gid :gid_t; - dr_mode :mode_t; - dr_incset:devfs_rsnum; { Included ruleset. } - end; - -const -{ - * Rule-related ioctls. - } - DEVFSIO_RADD =$C0F04400; - DEVFSIO_RDEL =$80044401; - DEVFSIO_RAPPLY =$80F04402; - DEVFSIO_RAPPLYID=$80044403; - DEVFSIO_RGETNEXT=$C0F04404; - - DEVFSIO_SUSE =$8002440A; - DEVFSIO_SAPPLY =$8002440B; - DEVFSIO_SGETNEXT=$C002440C; - -{ XXX: DEVFSIO_RS_GET_INFO for refcount, active if any, etc. } - - DE_WHITEOUT=$01; - DE_DOT =$02; - DE_DOTDOT =$04; - DE_DOOMED =$08; - DE_COVERED =$10; - DE_USER =$20; - - CDP_ACTIVE =(1 shl 0); - CDP_SCHED_DTR=(1 shl 1); - CDP_UNREF_DTR=(1 shl 2); - -type - t_cdpd_dtr=procedure(P:Pointer); - - p_cdev_privdata=^t_cdev_privdata; - t_cdev_privdata=packed record - cdpd_fp :p_file; - cdpd_data:Pointer; - cdpd_dtr :t_cdpd_dtr; - cdpd_list:LIST_ENTRY; //cdev_privdata - end; - - pp_devfs_dirent=^p_devfs_dirent; - p_devfs_dirent=^t_devfs_dirent; - - p_cdev_priv=^t_cdev_priv; - t_cdev_priv=packed record - cdp_c:t_cdev; - cdp_list:TAILQ_ENTRY; //cdev_priv - - cdp_inode:DWORD; - cdp_flags:DWORD; - - cdp_inuse :DWORD; - cdp_maxdirent:DWORD; - - cdp_dirents:pp_devfs_dirent; - cdp_dirent0:p_devfs_dirent; - - cdp_dtr_list:TAILQ_ENTRY; //cdev_priv - - cdp_dtr_cb :t_cdpd_dtr; - cdp_dtr_cb_arg:Pointer; - - cdp_fdpriv:LIST_HEAD; //cdev_privdata - end; - - devfs_dlist_head=TAILQ_HEAD; //devfs_dirent - - t_devfs_dirent=record - de_cdp :p_cdev_priv; - de_inode :Integer; - de_flags :Integer; - de_holdcnt:Integer; - de_dirent :p_dirent; - de_list :TAILQ_ENTRY; - de_dlist :devfs_dlist_head; - de_dir :p_devfs_dirent; - de_links :Integer; - de_mode :mode_t; - de_uid :uid_t; - de_gid :gid_t; - //label *de_label; - de_atime :timespec; - de_mtime :timespec; - de_ctime :timespec; - de_vnode :p_vnode; - de_symlink:PChar; - end; - - p_devfs_mount=^t_devfs_mount; - t_devfs_mount=record - dm_idx :DWORD ; - dm_mount :p_mount ; - dm_rootdir :p_devfs_dirent; - dm_generation:DWORD ; - dm_holdcnt :Integer ; - dm_lock :t_sx ; - dm_ruleset :devfs_rsnum ; - end; - -const - DEVFS_ROOTINO=2; - - DEVFS_DEL_VNLOCKED =$01; - DEVFS_DEL_NORECURSE=$02; - -var - devfs_rule_depth:DWORD=0; + sys_conf, + kern_mtx; function rid2rsn(rid:devfs_rid):devfs_rsnum; function rid2rn (rid:devfs_rid):devfs_rnum; @@ -210,58 +27,38 @@ function DEVFS_DMP_DROP(dmp:p_devfs_mount):Boolean; // -type - p_dirlistent=^t_dirlistent; - t_dirlistent=record - dir :PChar; - refcnt:Integer; - link :LIST_ENTRY; //dirlistent - end; - -var - devfs_dirlist:LIST_HEAD=(lh_first:nil); //dirlistent - dirlist_mtx :mtx; //MTX_SYSINIT(dirlist_mtx, &dirlist_mtx, "devfs dirlist lock", MTX_DEF); - - devfs_de_interlock:mtx; //MTX_SYSINIT(devfs_de_interlock, @devfs_de_interlock, 'devfs interlock', MTX_DEF); - cdevpriv_mtx :mtx; //MTX_SYSINIT(cdevpriv_mtx, @cdevpriv_mtx, 'cdevpriv lock', MTX_DEF); - clone_drain_lock :t_sx=(n:'clone events drain lock';c:nil;m:0); - - devfs_generation:DWORD=0; - function devfs_dir_find(path:PChar):Integer; -function devfs_dir_findent_locked(dir:PChar):p_dirlistent; -procedure devfs_dir_ref(dir:PChar); procedure devfs_dir_ref_de(dm:p_devfs_mount;de:p_devfs_dirent); -procedure devfs_dir_unref(dir:PChar); procedure devfs_dir_unref_de(dm:p_devfs_mount;de:p_devfs_dirent); function devfs_pathpath(p1,p2:PChar):Integer; procedure devfs_mtx_init; -var - cdevp_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@cdevp_list.tqh_first); - -function devfs_alloc(flags:Integer):p_cdev; external; -function devfs_dev_exists(name:PChar):Integer; external; -procedure devfs_free(cdev:p_cdev); external; -function devfs_find(dd:p_devfs_dirent;name:PChar;namelen:Integer;_type:Integer):p_devfs_dirent; external; -function devfs_newdirent(name:PChar;namelen:Integer):p_devfs_dirent; external; -function devfs_parent_dirent(de:p_devfs_dirent):p_devfs_dirent; external; -function devfs_vmkdir(dmp:p_devfs_mount;name:PChar;namelen:Integer;dotdot:p_devfs_dirent;inode:DWORD):p_devfs_dirent; external; -procedure devfs_dirent_free(de:p_devfs_dirent); external; -procedure devfs_rmdir_empty(dm:p_devfs_mount;de:p_devfs_dirent); external; -procedure devfs_delete(dm:p_devfs_mount;de:p_devfs_dirent;flags:Integer); external; -procedure devfs_purge(dm:p_devfs_mount;dd:p_devfs_dirent); external; -procedure devfs_metoo(cdp:p_cdev_priv;dm:p_devfs_mount); external; -function devfs_populate_loop(dm:p_devfs_mount;cleanup:Integer):Integer; external; -procedure devfs_populate(dm:p_devfs_mount); external; -procedure devfs_cleanup(dm:p_devfs_mount); external; -procedure devfs_create(dev:p_cdev); external; -procedure devfs_destroy(dev:p_cdev); external; -function devfs_alloc_cdp_inode():ino_t; external; -procedure devfs_free_cdp_inode(ino:ino_t); external; +procedure devfs_rules_apply(dm:p_devfs_mount;de:p_devfs_dirent); external; +procedure devfs_rules_cleanup(dm:p_devfs_mount); external; +function devfs_rules_ioctl(dm:p_devfs_mount;cmd:QWORD;data:Pointer):Integer; external; +procedure devfs_ruleset_set(rsnum:devfs_rsnum;dm:p_devfs_mount); external; +procedure devfs_ruleset_apply(dm:p_devfs_mount); external; +function devfs_allocv(de:p_devfs_dirent;mp:p_mount;lockmode:Integer;vpp:pp_vnode):Integer; external; function devfs_fqpn(buf:PChar;dmp:p_devfs_mount;dd:p_devfs_dirent;cnp:Pointer):PChar; external; +procedure devfs_delete(dm:p_devfs_mount;de:p_devfs_dirent;flags:Integer); external; +procedure devfs_dirent_free(de:p_devfs_dirent); external; +procedure devfs_populate(dm:p_devfs_mount); external; +procedure devfs_cleanup(dm:p_devfs_mount); external; + +procedure devfs_unmount_final(fmp:p_devfs_mount); external; + +function devfs_newdirent(name:PChar;namelen:Integer):p_devfs_dirent; external; +function devfs_parent_dirent(de:p_devfs_dirent):p_devfs_dirent; external; +function devfs_vmkdir(dmp:p_devfs_mount; + name:PChar;namelen:Integer; + dotdot:p_devfs_dirent; + inode:DWORD):p_devfs_dirent; external; +function devfs_find(dd:p_devfs_dirent; + name:PChar;namelen:Integer; + _type:Integer):p_devfs_dirent; external; + implementation { @@ -307,7 +104,7 @@ end; // { Exits 1 if the path is in the directory list. } -function devfs_dir_find(path:PChar):Integer; +function devfs_dir_find(path:PChar):Integer; public; var dle:p_dirlistent; begin @@ -414,7 +211,7 @@ begin end; end; -procedure devfs_dir_unref_de(dm:p_devfs_mount;de:p_devfs_dirent); +procedure devfs_dir_unref_de(dm:p_devfs_mount;de:p_devfs_dirent); public; var dirname:array[0..SPECNAMELEN] of AnsiChar; namep:PChar; @@ -426,7 +223,7 @@ begin end; { Exits 1 if the path p1 contains the path p2. } -function devfs_pathpath(p1,p2:PChar):Integer; +function devfs_pathpath(p1,p2:PChar):Integer; public; begin repeat if (p1^<>p2^) then diff --git a/sys/fs/devfs/devfs_devs.pas b/sys/fs/devfs/devfs_devs.pas index 25607a50..19779660 100644 --- a/sys/fs/devfs/devfs_devs.pas +++ b/sys/fs/devfs/devfs_devs.pas @@ -8,7 +8,8 @@ interface uses mqueue, kern_id, - kern_conf, + sys_conf, + devfs_int, devfs; function devfs_alloc(flags:Integer):p_cdev; @@ -42,8 +43,7 @@ uses kern_sx, vfs_vnops, vfs_subr, - vnode_if, - devfs_rule; + vnode_if; var devfs_desc:t_id_desc=(free:nil;refs:0); diff --git a/sys/fs/devfs/devfs_rule.pas b/sys/fs/devfs/devfs_rule.pas index c4770d84..b66edd57 100644 --- a/sys/fs/devfs/devfs_rule.pas +++ b/sys/fs/devfs/devfs_rule.pas @@ -8,7 +8,8 @@ interface uses mqueue, kern_param, - kern_conf, + sys_conf, + devfs_int, devfs, kern_sx; @@ -84,7 +85,7 @@ uses * exposed to the userland. This should be called with an exclusive * lock on dm in case we need to run anything. } -procedure devfs_rules_apply(dm:p_devfs_mount;de:p_devfs_dirent); +procedure devfs_rules_apply(dm:p_devfs_mount;de:p_devfs_dirent); public; var ds:p_devfs_ruleset; begin @@ -104,7 +105,7 @@ end; { * Rule subsystem ioctl hook. } -function devfs_rules_ioctl(dm:p_devfs_mount;cmd:QWORD;data:Pointer):Integer; +function devfs_rules_ioctl(dm:p_devfs_mount;cmd:QWORD;data:Pointer):Integer; public; label _break; var @@ -807,7 +808,7 @@ begin Exit(0); end; -procedure devfs_rules_cleanup(dm:p_devfs_mount); +procedure devfs_rules_cleanup(dm:p_devfs_mount); public; var ds:p_devfs_ruleset; begin @@ -823,7 +824,7 @@ end; { * Make rsnum the active ruleset for dm (locked) } -procedure devfs_ruleset_set(rsnum:devfs_rsnum;dm:p_devfs_mount); +procedure devfs_ruleset_set(rsnum:devfs_rsnum;dm:p_devfs_mount); public; begin sx_assert(@dm^.dm_lock); sx_xlock(@sx_rules); @@ -834,7 +835,7 @@ end; { * Apply the current active ruleset on a mount } -procedure devfs_ruleset_apply(dm:p_devfs_mount); +procedure devfs_ruleset_apply(dm:p_devfs_mount); public; var ds:p_devfs_ruleset; begin diff --git a/sys/fs/devfs/devfs_vfsops.pas b/sys/fs/devfs/devfs_vfsops.pas index a4275246..25f78b66 100644 --- a/sys/fs/devfs/devfs_vfsops.pas +++ b/sys/fs/devfs/devfs_vfsops.pas @@ -9,6 +9,7 @@ uses kern_param, vnode, vmount, + devfs_int, devfs, kern_id; @@ -66,13 +67,7 @@ uses vfs_mount, vfs_subr, vnode_if, - devfs_rule; - -// - -function devfs_allocv(de:p_devfs_dirent;mp:p_mount;lockmode:Integer;vpp:pp_vnode):Integer; external; - -// + devfs_devs; var unr_desc:t_id_desc=(free:nil;refs:0); @@ -217,7 +212,7 @@ begin Exit(0); end; -procedure devfs_unmount_final(fmp:p_devfs_mount); +procedure devfs_unmount_final(fmp:p_devfs_mount); public; begin sx_destroy(@fmp^.dm_lock); FreeMem(fmp); diff --git a/sys/fs/devfs/devfs_vnops.pas b/sys/fs/devfs/devfs_vnops.pas index 39b774d1..07b4e278 100644 --- a/sys/fs/devfs/devfs_vnops.pas +++ b/sys/fs/devfs/devfs_vnops.pas @@ -23,10 +23,11 @@ uses vnode_if, vfs_default, vfs_vnops, + devfs_int, devfs, kern_mtx, kern_sx, - kern_conf; + sys_conf; function devfs_fp_check(fp:p_file;devp:pp_cdev;dswp:pp_cdevsw;ref:PInteger):Integer; function devfs_get_cdevpriv(datap:PPointer):Integer; @@ -200,8 +201,7 @@ uses kern_thr, vfs_subr, vsys_generic, - devfs_rule, - devfs_vfsops, + //devfs_vfsops, kern_proc, kern_descrip, kern_mtxpool, @@ -236,7 +236,7 @@ begin Exit(0); end; -function devfs_get_cdevpriv(datap:PPointer):Integer; +function devfs_get_cdevpriv(datap:PPointer):Integer; public; var fp:p_file; p:p_cdev_privdata; @@ -258,7 +258,7 @@ begin Exit(error); end; -function devfs_set_cdevpriv(priv:Pointer;priv_dtr:cdevpriv_dtr_t):Integer; +function devfs_set_cdevpriv(priv:Pointer;priv_dtr:cdevpriv_dtr_t):Integer; public; var fp:p_file; cdp:p_cdev_priv; @@ -289,7 +289,7 @@ begin Exit(error); end; -procedure devfs_destroy_cdevpriv(p:p_cdev_privdata); +procedure devfs_destroy_cdevpriv(p:p_cdev_privdata); public; begin mtx_assert(cdevpriv_mtx); p^.cdpd_fp^.f_cdevpriv:=nil; @@ -299,7 +299,7 @@ begin FreeMem(p); end; -procedure devfs_fpdrop(fp:p_file); +procedure devfs_fpdrop(fp:p_file); public; var p:p_cdev_privdata; begin @@ -313,7 +313,7 @@ begin devfs_destroy_cdevpriv(p); end; -procedure devfs_clear_cdevpriv(); +procedure devfs_clear_cdevpriv(); public; var fp:p_file; begin diff --git a/sys/host_ipc.pas b/sys/host_ipc.pas index 83cc30fd..503edef9 100644 --- a/sys/host_ipc.pas +++ b/sys/host_ipc.pas @@ -6,17 +6,20 @@ interface uses Classes, + time, mqueue, LFQueue, kern_thr, kern_thread, + sys_event, kern_mtx; type t_mtype=( iRESULT, - iMOUNT, - iKNOTE + iKEV_CHANGE, + iKEV_EVENT, + iMOUNT ); PNodeHeader=^TNodeHeader; @@ -42,13 +45,6 @@ type tid :DWORD; end; - PHostIpcKnote=^THostIpcKnote; - THostIpcKnote=packed record - pid :Integer; - filter:Integer; - hint :QWORD - end; - THostIpcHandler=class function OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint; virtual; end; @@ -58,6 +54,7 @@ type FQueue:TIntrusiveMPSCQueue; FWaits:LIST_HEAD; FWLock:mtx; + Fkq:Pointer; procedure SyncResult(tid:DWORD;value:Ptruint); function NewNodeSync:PNodeIpcSync; procedure FreeNodeSync(node:PNodeIpcSync); @@ -66,9 +63,12 @@ type function Recv:PQNode; procedure Flush; procedure RecvSync(node:PQNode); + procedure RecvKevent(node:PQNode); + procedure UpdateKevent(); + procedure WakeupKevent(); virtual; public // - procedure knote(pid,filter:Integer;hint:QWORD); + procedure kevent(kev:p_kevent;count:Integer); // function SendSync(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint; procedure SendAsyn(mtype:t_mtype;mlen:DWORD;buf:Pointer); @@ -77,6 +77,8 @@ type // Constructor Create; Destructor Destroy; override; + procedure thread_new; virtual; + procedure thread_free; virtual; end; THostIpcSimpleKERN=class; @@ -93,15 +95,17 @@ type FHandler:THostIpcHandler; Constructor Create; Destructor Destroy; override; + procedure thread_new; override; + procedure thread_free; override; procedure Send(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer); override; - procedure Update(Handler:THostIpcHandler); override; + procedure WakeupKevent(); override; end; implementation function THostIpcHandler.OnMessage(mtype:t_mtype;mlen:DWORD;buf:Pointer):Ptruint; begin - // + Result:=0; end; Constructor THostIpcConnect.Create; @@ -115,9 +119,23 @@ Destructor THostIpcConnect.Destroy; begin Flush; mtx_destroy(FWLock); + if (Fkq<>nil) then + begin + kqueue_close2(Fkq); + end; inherited; end; +procedure THostIpcConnect.thread_new; +begin + // +end; + +procedure THostIpcConnect.thread_free; +begin + // +end; + procedure THostIpcConnect.Pack(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer); var node:PQNode; @@ -166,6 +184,64 @@ begin TriggerNodeSync(node^.header.mtid,value); end; +procedure kq_wakeup(data:Pointer); SysV_ABI_CDecl; +begin + THostIpcConnect(data).WakeupKevent(); +end; + +procedure THostIpcConnect.RecvKevent(node:PQNode); +var + kev:p_kevent; + value:Ptruint; + count:Integer; +begin + kev :=@node^.buf; + count:=node^.header.mlen div SizeOf(t_kevent); + + Writeln('RecvKevent ',kev^.ident,' ',count); + + if (Fkq=nil) then + begin + Fkq:=kern_kqueue2('[ipc]',@kq_wakeup,Pointer(Self)); + end; + + //changelist + value:=kern_kevent2(Fkq,kev,count,nil,0,nil,@count); + + //is sync + if (node^.header.mtid<>0) then + begin + SyncResult(node^.header.mtid,value); + end; +end; + +procedure THostIpcConnect.UpdateKevent(); +var + kev:array[0..7] of t_kevent; + t:timespec; + r:Integer; +begin + if (Fkq=nil) then Exit; + t:=Default(timespec); + + repeat + + r:=0; + kern_kevent2(Fkq,nil,0,@kev,8,@t,@r); + + if (r>0) then + begin + SendAsyn(iKEV_EVENT,r*SizeOf(t_kevent),@kev); + end; + + until (r<>8); +end; + +procedure THostIpcConnect.WakeupKevent(); +begin + // +end; + procedure THostIpcConnect.Update(Handler:THostIpcHandler); var node:PQNode; @@ -175,21 +251,25 @@ begin while (node<>nil) do begin // - if (node^.header.mtype=DWORD(iRESULT)) then - begin - RecvSync(node); - end else - if (Handler<>nil) then - begin - value:=Handler.OnMessage(t_mtype(node^.header.mtype),node^.header.mlen,@node^.buf); - //is sync - if (node^.header.mtid<>0) then - begin - SyncResult(node^.header.mtid,value); - end; + case t_mtype(node^.header.mtype) of + iRESULT :RecvSync(node); + iKEV_CHANGE:RecvKevent(node); + else + if (Handler<>nil) then + begin + value:=Handler.OnMessage(t_mtype(node^.header.mtype),node^.header.mlen,@node^.buf); + + //is sync + if (node^.header.mtid<>0) then + begin + SyncResult(node^.header.mtid,value); + end; + + end; end; + // FreeMem(node); // @@ -204,15 +284,9 @@ begin Send(iRESULT,SizeOf(Ptruint),tid,@value); end; -procedure THostIpcConnect.knote(pid,filter:Integer;hint:QWORD); -var - note:THostIpcKnote; +procedure THostIpcConnect.kevent(kev:p_kevent;count:Integer); begin - note.pid :=pid; - note.filter:=filter; - note.hint :=hint; - // - SendAsyn(iKNOTE,SizeOf(note),@note); + SendAsyn(iKEV_CHANGE,count*SizeOf(t_kevent),kev); end; // @@ -312,6 +386,10 @@ begin ipc:=THostIpcSimpleKERN(parameter); repeat + if ipc.FQueue.IsEmpty then + begin + RTLEventWaitFor(ipc.FEvent); + end; ipc.Update(ipc.FHandler); until false; @@ -321,24 +399,30 @@ Constructor THostIpcSimpleKERN.Create; begin inherited; FEvent:=RTLEventCreate; - Ftd:=nil; - kthread_add(@simple_kern_thread,Self,@Ftd,'[ipc_pipe]'); end; Destructor THostIpcSimpleKERN.Destroy; begin - thread_dec_ref(Ftd); + thread_free; RTLEventDestroy(FEvent); inherited; end; -procedure THostIpcSimpleKERN.Update(Handler:THostIpcHandler); +procedure THostIpcSimpleKERN.thread_new; begin - if FQueue.IsEmpty then + if (Ftd=nil) then begin - RTLEventWaitFor(FEvent); + kthread_add(@simple_kern_thread,Self,@Ftd,'[ipc_pipe]'); + end; +end; + +procedure THostIpcSimpleKERN.thread_free; +begin + if (Ftd<>nil) then + begin + thread_dec_ref(Ftd); + Ftd:=nil; end; - inherited Update(Handler); end; procedure THostIpcSimpleKERN.Send(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer); @@ -355,5 +439,10 @@ begin end; end; +procedure THostIpcSimpleKERN.WakeupKevent(); +begin + UpdateKevent(); +end; + end. diff --git a/sys/kern/kern_blockpool.pas b/sys/kern/kern_blockpool.pas index 6b300838..370f01da 100644 --- a/sys/kern/kern_blockpool.pas +++ b/sys/kern/kern_blockpool.pas @@ -15,7 +15,7 @@ uses kern_descrip, vfile, vfcntl, - kern_conf, + sys_conf, vstat; function blockpool_ioctl(fp:p_file;com:QWORD;data:Pointer):Integer; diff --git a/sys/kern/kern_event.pas b/sys/kern/kern_event.pas index a6d2cae1..3cbd0ee8 100644 --- a/sys/kern/kern_event.pas +++ b/sys/kern/kern_event.pas @@ -99,18 +99,18 @@ function kqfd_register(fd:Integer;kev:p_kevent):Integer; function sys_kqueue():Integer; function sys_kqueueex(name:PChar):Integer; -function sys_kevent(fd:Integer; + +function sys_kevent(fd :Integer; changelist:Pointer; - nchanges:Integer; - eventlist:Pointer; - nevents:Integer; - timeout:Pointer):Integer; + nchanges :Integer; + eventlist :Pointer; + nevents :Integer; + timeout :Pointer):Integer; implementation uses errno, - md_proc, md_time, kern_sig, kern_sx, @@ -438,7 +438,7 @@ begin immediate:=1; end; - kn^.kn_ptr.p_proc:=nil; + kn^.kn_ptr.p_proc:=@p_proc; kn^.kn_flags:=kn^.kn_flags or EV_CLEAR; { automatically set } { @@ -453,7 +453,7 @@ begin if (immediate=0) then begin - knlist_add(@p_proc.p_klist, kn, 1); + knlist_add(@p_proc.p_klist, kn, 0); end; { @@ -843,7 +843,34 @@ end; // -function kern_kqueue(pfd:PInteger;name:PAnsiChar):Integer; +function kern_kqueue2(name:PAnsiChar; + w_cb:t_kqueue_wakeup_cb; + data:Pointer):p_kqueue; public; +var + kq:p_kqueue; +begin + kq:=AllocMem(SizeOf(t_kqueue)); + if (kq=nil) then Exit; + + mtx_init(kq^.kq_lock, 'kqueue'); + TAILQ_INIT(@kq^.kq_head); + //kq^.kq_fdp:=fdp; + knlist_init_mtx(@kq^.kq_sel.si_note, @kq^.kq_lock); + //TASK_INIT(@kq^.kq_task, 0, kqueue_task, kq); + + if (name<>nil) then + begin + kq^.kq_name:=name; + end; + + kq^.kq_wakeup:=w_cb; + kq^.kq_data :=data; + + Result:=kq; +end; + +function kern_kqueue(pfd :PInteger; + name:PAnsiChar):Integer; var kq:p_kqueue; fp:p_file; @@ -856,18 +883,9 @@ begin if (error<>0) then Exit(error); { An extra reference on `nfp' has been held for us by falloc(). } - kq:=AllocMem(SizeOf(t_kqueue)); - mtx_init(kq^.kq_lock, 'kqueue'); - TAILQ_INIT(@kq^.kq_head); - //kq^.kq_fdp:=fdp; - knlist_init_mtx(@kq^.kq_sel.si_note, @kq^.kq_lock); - //TASK_INIT(@kq^.kq_task, 0, kqueue_task, kq); - - if (name<>nil) then - begin - kq^.kq_name:=name; - end; + kq:=kern_kqueue2(name,nil,nil); + if (kq=nil) then Exit(ENOMEM); FILEDESC_XLOCK(@fd_table); TAILQ_INSERT_HEAD(@fd_table.fd_kqlist, kq, @kq^.kq_list); @@ -922,12 +940,10 @@ end; type p_kevent_args=^t_kevent_args; t_kevent_args=record - fd :Integer; changelist:p_kevent; nchanges :Integer; eventlist :p_kevent; nevents :Integer; - timeout :p_timespec; end; { @@ -949,6 +965,19 @@ begin Exit(error); end; +function kevent_copyout2(arg:Pointer;kevp:p_kevent;count:Integer):Integer; +var + uap:p_kevent_args; +begin + Assert(count <= KQ_NEVENTS, Format('count (%d) > KQ_NEVENTS', [count])); + uap:=arg; + + Move(kevp^,uap^.eventlist^,count*sizeof(t_kevent)); + + Inc(uap^.eventlist,count); + Result:=0; +end; + { * Copy 'count' items from the list pointed to by uap^.changelist. } @@ -968,23 +997,97 @@ begin Exit(error); end; +function kevent_copyin2(arg:Pointer;kevp:p_kevent;count:Integer):Integer; +var + uap:p_kevent_args; +begin + Assert(count <= KQ_NEVENTS, Format('count (%d) > KQ_NEVENTS', [count])); + uap:=arg; + + Move(uap^.changelist^,kevp^,count*sizeof(t_kevent)); + + Inc(uap^.changelist,count); + Result:=0; +end; + +function _kern_kevent(td:p_kthread; + kq:p_kqueue; + nchanges:Integer; + nevents:Integer; + k_ops:p_kevent_copyops; + timeout:p_timespec):Integer; +type + t_keva=array[0..KQ_NEVENTS-1] of t_kevent; +var + keva:t_keva; + kevp,changes:p_kevent; + i,n,nerrors:Integer; +begin + Result:=0; + + nerrors:=0; + keva:=Default(t_keva); + + while (nchanges > 0) do + begin + if (nchanges > KQ_NEVENTS) then + n:=KQ_NEVENTS + else + n:=nchanges; + + Result:=k_ops^.k_copyin(k_ops^.arg, keva, n); + if (Result<>0) then Exit; //goto done; + + changes:=keva; + + For i:=0 to n-1 do + begin + kevp:=@changes[i]; + if (kevp^.filter=0) then continue; + kevp^.flags:=kevp^.flags and (not EV_SYSFLAGS); + Result:=kqueue_register(kq, kevp); + if (Result<>0) or ((kevp^.flags and EV_RECEIPT)<>0) then + begin + if (nevents<>0) then + begin + kevp^.flags:=EV_ERROR; + kevp^.data :=Result; + k_ops^.k_copyout(k_ops^.arg, kevp, 1); + Dec(nevents); + Inc(nerrors); + end else + begin + Exit(0); //goto done; + end; + end; + end; + + Dec(nchanges,n); + end; + + if (nerrors<>0) then + begin + td^.td_retval[0]:=nerrors; + Exit(0); //goto done; + end; + + Result:=kqueue_scan(kq, nevents, k_ops, timeout, keva); +end; + function kern_kevent(fd:Integer; nchanges:Integer; nevents:Integer; k_ops:p_kevent_copyops; timeout:p_timespec):Integer; label - done_norel, - done; + done_norel; type t_keva=array[0..KQ_NEVENTS-1] of t_kevent; var td:p_kthread; - keva:t_keva; - kevp,changes:p_kevent; kq:p_kqueue; fp:p_file; - i,n,nerrors,error:Integer; + error:Integer; begin td:=curkthread; if (td=nil) then Exit(-1); @@ -1007,64 +1110,27 @@ begin Writeln('kern_kevent:',kq^.kq_name); - nerrors:=0; - keva:=Default(t_keva); + error:=_kern_kevent(td, + kq, + nchanges, + nevents, + k_ops, + timeout); - while (nchanges > 0) do - begin - if (nchanges > KQ_NEVENTS) then - n:=KQ_NEVENTS - else - n:=nchanges; - - error:=k_ops^.k_copyin(k_ops^.arg, keva, n); - if (error<>0) then goto done; - changes:=keva; - For i:=0 to n-1 do - begin - kevp:=@changes[i]; - if (kevp^.filter=0) then continue; - kevp^.flags:=kevp^.flags and (not EV_SYSFLAGS); - error:=kqueue_register(kq, kevp); - if (error<>0) or ((kevp^.flags and EV_RECEIPT)<>0) then - begin - if (nevents<>0) then - begin - kevp^.flags:=EV_ERROR; - kevp^.data :=error; - k_ops^.k_copyout(k_ops^.arg, kevp, 1); - Dec(nevents); - Inc(nerrors); - end else - begin - goto done; - end; - end; - end; - Dec(nchanges,n); - end; - - if (nerrors<>0) then - begin - td^.td_retval[0]:=nerrors; - error:=0; - goto done; - end; - - error:=kqueue_scan(kq, nevents, k_ops, timeout, keva); -done: +//done: kqueue_release(kq, 0); + done_norel: fdrop(fp); Exit(error); end; -function sys_kevent(fd:Integer; +function sys_kevent(fd :Integer; changelist:Pointer; - nchanges:Integer; - eventlist:Pointer; - nevents:Integer; - timeout:Pointer):Integer; + nchanges :Integer; + eventlist :Pointer; + nevents :Integer; + timeout :Pointer):Integer; var ts:timespec; tsp:p_timespec; @@ -1082,12 +1148,10 @@ begin tsp:=nil; end; - uap.fd :=fd ; uap.changelist:=changelist; uap.nchanges :=nchanges ; uap.eventlist :=eventlist ; uap.nevents :=nevents ; - uap.timeout :=timeout ; k_ops.arg :=@uap; k_ops.k_copyout:=@kevent_copyout; @@ -1098,7 +1162,44 @@ begin Exit(error); end; -function kqueue_add_filteropts(filt:Integer;filtops:p_filterops):Integer; +function kern_kevent2(kq :p_kqueue; + changelist:p_kevent; + nchanges :Integer; + eventlist :p_kevent; + nevents :Integer; + timeout :p_timespec; + p_ncount :PInteger):Integer; public; +var + td:p_kthread; + error:Integer; + uap:t_kevent_args; + k_ops:t_kevent_copyops; +begin + td:=curkthread; + if (td=nil) then Exit(-1); + + uap.changelist:=changelist; + uap.nchanges :=nchanges ; + uap.eventlist :=eventlist ; + uap.nevents :=nevents ; + + k_ops.arg :=@uap; + k_ops.k_copyout:=@kevent_copyout2; + k_ops.k_copyin :=@kevent_copyin2; + + error:=_kern_kevent(td, + kq, + nchanges, + nevents, + @k_ops, + timeout); + + p_ncount^:=td^.td_retval[0]; + + Exit(error); +end; + +function kqueue_add_filteropts(filt:Integer;filtops:p_filterops):Integer; public; var error:Integer; begin @@ -1123,7 +1224,7 @@ begin Exit(error); end; -function kqueue_del_filteropts(filt:Integer):Integer; +function kqueue_del_filteropts(filt:Integer):Integer; public; var error:Integer; begin @@ -1349,7 +1450,7 @@ findkn: kev^.fflags:=0; kev^.data:=0; kn^.kn_kevent:=kev^; - kn^.kn_kevent.flags:=kn^.kn_kevent.flags and (not (EV_ADD or EV_DELETE or EV_ENABLE or EV_DISABLE)); + kn^.kn_kevent.flags:=kn^.kn_kevent.flags and (not EV_ACTION); kn^.kn_status:=KN_INFLUX or KN_DETACHED; error:=knote_attach(kn, kq); @@ -1462,7 +1563,7 @@ done: Exit(error); end; -procedure kqueue_deregister(filter:SmallInt;pid,ident:PtrUint); +procedure kqueue_deregister(filter:SmallInt;pid,ident:PtrUint); public; label _lock, _again; @@ -2018,21 +2119,13 @@ begin Exit(0); end; -{ARGSUSED} -function kqueue_close(fp:p_file):Integer; +procedure kqueue_close2(kq:p_kqueue); public; var - kq:p_kqueue; kn:p_knote; i:Integer; - error:Integer; - filedesc_unlock:Integer; begin - kq:=fp^.f_data; + if (kq=nil) then Exit; - error:=kqueue_acquire(fp, @kq); - if (error<>0) then Exit(error); - - filedesc_unlock:=0; KQ_LOCK(kq); Assert((kq^.kq_state and KQ_CLOSING)<>KQ_CLOSING,'kqueue already closing'); @@ -2120,6 +2213,39 @@ begin KQ_UNLOCK(kq); + seldrain(@kq^.kq_sel); + knlist_destroy(@kq^.kq_sel.si_note); + mtx_destroy(kq^.kq_lock); + //kq^.kq_fdp:=nil; + + if (kq^.kq_knhash<>nil) then + begin + FreeMem(kq^.kq_knhash); + end; + if (kq^.kq_knlist<>nil) then + begin + FreeMem(kq^.kq_knlist); + end; + + //funsetown(@kq^.kq_sigio); + + FreeMem(kq); +end; + +{ARGSUSED} +function kqueue_close(fp:p_file):Integer; +var + kq:p_kqueue; + error:Integer; + filedesc_unlock:Integer; +begin + kq:=fp^.f_data; + + error:=kqueue_acquire(fp, @kq); + if (error<>0) then Exit(error); + + filedesc_unlock:=0; + { * We could be called due to the knote_drop() doing fdrop(), * called from kqueue_register(). In this case the global @@ -2142,22 +2268,8 @@ begin FILEDESC_XUNLOCK(@fd_table); end; - seldrain(@kq^.kq_sel); - knlist_destroy(@kq^.kq_sel.si_note); - mtx_destroy(kq^.kq_lock); - //kq^.kq_fdp:=nil; + kqueue_close2(kq); - if (kq^.kq_knhash<>nil) then - begin - FreeMem(kq^.kq_knhash); - end; - if (kq^.kq_knlist<>nil) then - begin - FreeMem(kq^.kq_knlist); - end; - - //funsetown(@kq^.kq_sigio); - FreeMem(kq); fp^.f_data:=nil; Exit(0); @@ -2188,6 +2300,12 @@ begin begin //pgsigio(@kq^.kq_sigio, SIGIO, 0); end; + + if (kq^.kq_wakeup<>nil) then + begin + kq^.kq_wakeup(kq^.kq_data); + end; + end; { @@ -2655,6 +2773,7 @@ begin TAILQ_INSERT_TAIL(@kq^.kq_head,kn,@kn^.kn_tqe); kn^.kn_status:=kn^.kn_status or KN_QUEUED; Inc(kq^.kq_count); + kqueue_wakeup(kq); end; @@ -2697,7 +2816,7 @@ end; { * Register the kev w/ the kq specified by fd. } -function kqfd_register(fd:Integer;kev:p_kevent):Integer; +function kqfd_register(fd:Integer;kev:p_kevent):Integer; public; label noacquire; var diff --git a/sys/kern/kern_exec.pas b/sys/kern/kern_exec.pas index 8c04eb29..71eed5ba 100644 --- a/sys/kern/kern_exec.pas +++ b/sys/kern/kern_exec.pas @@ -59,7 +59,6 @@ uses sys_resource, kern_resource, sys_event, - kern_event, machdep, kern_dlsym, kern_authinfo, diff --git a/sys/kern/kern_exit.pas b/sys/kern/kern_exit.pas index a1fd6566..fdb383fb 100644 --- a/sys/kern/kern_exit.pas +++ b/sys/kern/kern_exit.pas @@ -70,7 +70,7 @@ uses systm, kern_proc, sys_event, - kern_event, + md_sleep, md_proc; function _WSTATUS(x:Integer):Integer; inline; @@ -136,6 +136,9 @@ begin if halt_on_exit then begin md_halt(rv); + end else + begin + msleep_td(0); end; end; diff --git a/sys/kern/kern_proc.pas b/sys/kern/kern_proc.pas index 5dbb0ded..b5bb3e02 100644 --- a/sys/kern/kern_proc.pas +++ b/sys/kern/kern_proc.pas @@ -129,48 +129,9 @@ begin mtx_unlock(p_proc.p_mtx); end; -function filt_host_ipc_attach(kn:p_knote):Integer; -begin - Result:=0; -end; - -procedure filt_host_ipc_detach(kn:p_knote); -begin - // -end; - -function filt_host_ipc_event(kn:p_knote;hint:QWORD):Integer; -begin - p_proc.p_host_ipc.knote(p_proc.p_pid,EVFILT_PROC,hint); - Result:=0; -end; - -const - filterops_host_ipc:t_filterops=( - f_isfd :0; - _align :0; - f_attach:@filt_host_ipc_attach; - f_detach:@filt_host_ipc_detach; - f_event :@filt_host_ipc_event; - ); - procedure PROC_INIT_HOST_IPC(host_ipc:THostIpcConnect); -var - kn:p_knote; begin - if (host_ipc=nil) then Exit; - p_proc.p_host_ipc:=host_ipc; - - kn:=knote_alloc(); - - kn^.kn_fop:=@filterops_host_ipc; - - kn^.kn_status:=KN_INFLUX or KN_DETACHED or KN_SCAN; - kn^.kn_ptr.p_proc:=@p_proc; - kn^.kn_flags:=kn^.kn_flags or EV_CLEAR; - - knlist_add(@p_proc.p_klist, kn, 0); end; procedure PROC_INIT; diff --git a/sys/kern/uipc_syscalls.pas b/sys/kern/uipc_syscalls.pas index 1887a4a1..4a1e88be 100644 --- a/sys/kern/uipc_syscalls.pas +++ b/sys/kern/uipc_syscalls.pas @@ -14,7 +14,7 @@ implementation uses kern_thr, kern_descrip, - kern_conf, + sys_conf, vsocket, vfile, vfcntl, diff --git a/sys/md/md_exception.pas b/sys/md/md_exception.pas index ef635123..a4c98acb 100644 --- a/sys/md/md_exception.pas +++ b/sys/md/md_exception.pas @@ -13,6 +13,7 @@ uses machdep, md_context, md_proc, + kern_exit, kern_thr, subr_backtrace, trap, @@ -330,8 +331,6 @@ begin Writeln(stderr,_get_msg(Msg),' (',FName,', line ',LineNo,').'); print_backtrace(stderr,Get_pc_addr,get_frame,2); - //sleep(-1); - if IsDebuggerPresent then Raise EAssertionFailed. Createfmt('%s (%s, line %d).', @@ -343,9 +342,7 @@ begin // int3 //end; - sleep(-1); - - md_halt(217); + kern_exit.exit1(217); end; var diff --git a/sys/md/md_host_ipc.pas b/sys/md/md_host_ipc.pas index feec941e..50b89b87 100644 --- a/sys/md/md_host_ipc.pas +++ b/sys/md/md_host_ipc.pas @@ -35,9 +35,8 @@ type procedure set_pipe(fd:THandle); procedure Recv; virtual; Function Push(Node:Pointer):Boolean; virtual; - procedure thread_new; virtual; - procedure thread_free; virtual; procedure Send(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer); override; + procedure WakeupKevent(); override; Constructor Create; Destructor Destroy; override; end; @@ -168,26 +167,26 @@ begin Result:=FQueue.Push(node); end; -procedure THostIpcPipe.thread_new; -begin - // -end; - -procedure THostIpcPipe.thread_free; -begin - // -end; - procedure THostIpcPipe.Send(mtype:t_mtype;mlen,mtid:DWORD;buf:Pointer); begin proto.Send(mtype,mlen,mtid,buf); end; +Procedure ev_wakeup(param1:SizeUInt;param2:Pointer); register; +begin + THostIpcPipe(param2).UpdateKevent(); +end; + +procedure THostIpcPipe.WakeupKevent(); +begin + evpoll_post(@evpoll,@ev_wakeup,0,Pointer(Self)); +end; + Constructor THostIpcPipe.Create; begin inherited; evpoll_init(@evpoll,nil); - thread_new; + //thread_new; end; Destructor THostIpcPipe.Destroy; @@ -213,13 +212,20 @@ end; procedure THostIpcPipeMGUI.thread_new; begin - Ftd:=BeginThread(@pipe_gui_thread,@evpoll); + if (Ftd=0) then + begin + Ftd:=BeginThread(@pipe_gui_thread,@evpoll); + end; end; procedure THostIpcPipeMGUI.thread_free; begin - WaitForThreadTerminate(Ftd,0); - CloseThread(Ftd); + if (Ftd<>0) then + begin + WaitForThreadTerminate(Ftd,0); + CloseThread(Ftd); + Ftd:=0; + end; end; // @@ -233,13 +239,19 @@ end; procedure THostIpcPipeKERN.thread_new; begin - Ftd:=nil; - kthread_add(@pipe_kern_thread,@evpoll,@Ftd,'[ipc_pipe]'); + if (Ftd=nil) then + begin + kthread_add(@pipe_kern_thread,@evpoll,@Ftd,'[ipc_pipe]'); + end; end; procedure THostIpcPipeKERN.thread_free; begin - thread_dec_ref(Ftd); + if (Ftd<>nil) then + begin + thread_dec_ref(Ftd); + Ftd:=nil; + end; end; diff --git a/sys/md/md_systm.pas b/sys/md/md_systm.pas index fb94e10a..cd59b021 100644 --- a/sys/md/md_systm.pas +++ b/sys/md/md_systm.pas @@ -13,6 +13,12 @@ uses type t_fork_cb=procedure(data:Pointer;size:QWORD); SysV_ABI_CDecl; + p_fork_proc=^t_fork_proc; + t_fork_proc=record + hProcess:THandle; + fork_pid:Integer; + end; + function md_copyin (hProcess:THandle;udaddr,kaddr:Pointer;len:ptruint;lencopied:pptruint):Integer; function md_copyout(hProcess:THandle;kaddr,udaddr:Pointer;len:ptruint;lencopied:pptruint):Integer; @@ -25,7 +31,7 @@ function md_pidfd_open (pid:DWORD):THandle; procedure md_run_forked; procedure md_fork_unshare; -function md_fork_process(proc:Pointer;data:Pointer;size:QWORD):THandle; +function md_fork_process(proc:Pointer;data:Pointer;size:QWORD;var info:t_fork_proc):Integer; implementation @@ -172,23 +178,23 @@ function SetInformationJobObject(hJob:HANDLE; function AssignProcessToJobObject(hJob,hProcess:THandle):BOOL; stdcall; external kernel32; -function NtQueryTeb(td_handle:THandle):p_teb; +function NtQueryTeb(td_handle:THandle;var teb:p_teb):Integer; var TBI:THREAD_BASIC_INFORMATION; - err:Integer; begin - Result:=nil; + Result:=0; + teb:=nil; TBI:=Default(THREAD_BASIC_INFORMATION); - err:=NtQueryInformationThread( - td_handle, - ThreadBasicInformation, - @TBI, - SizeOf(THREAD_BASIC_INFORMATION), - nil); - if (err<>0) then Exit; + Result:=NtQueryInformationThread( + td_handle, + ThreadBasicInformation, + @TBI, + SizeOf(THREAD_BASIC_INFORMATION), + nil); + if (Result<>0) then Exit; - Result:=TBI.TebBaseAddress; + teb:=TBI.TebBaseAddress; end; procedure NtGetVirtualInfo(hProcess:THandle;var base:Pointer;var size:QWORD); @@ -259,8 +265,8 @@ begin err:=NtGetContextThread(hThread,Context); if (err<>0) then Exit(err); - teb:=NtQueryTeb(hThread); - if (teb=nil) then Exit(-1); + err:=NtQueryTeb(hThread,teb); + if (err<>0) then Exit(err); kstack:=Default(t_td_stack); err:=md_copyin(hProcess,@teb^.stack,@kstack,SizeOf(t_td_stack),nil); @@ -432,13 +438,15 @@ end; function NtCreateShared(hProcess:THandle;proc:Pointer;data:Pointer;size:QWORD):Integer; var base:p_shared_info; + full:QWORD; shared_info:t_shared_info; begin base:=Pointer(WIN_SHARED_ADDR); - size:=SizeOf(Pointer)+size; - size:=(size+(MD_PAGE_SIZE-1)) and (not (MD_PAGE_SIZE-1)); - Result:=md_mmap(hProcess,base,size,MD_PROT_RW); + full:=SizeOf(shared_info)+size; + full:=(size+(MD_PAGE_SIZE-1)) and (not (MD_PAGE_SIZE-1)); + + Result:=md_mmap(hProcess,base,full,MD_PROT_RW); if (Result<>0) then Exit; shared_info:=Default(t_shared_info); @@ -450,7 +458,6 @@ begin shared_info.hStdError :=md_dup_to_pidfd(hProcess,GetStdHandle(STD_ERROR_HANDLE)); shared_info.proc:=proc; - shared_info.size:=size; Result:=md_copyout(hProcess,@shared_info,base,SizeOf(shared_info),nil); @@ -462,7 +469,7 @@ begin end; end; -function md_fork_process(proc:Pointer;data:Pointer;size:QWORD):THandle; +function md_fork_process(proc:Pointer;data:Pointer;size:QWORD;var info:t_fork_proc):Integer; var si:TSTARTUPINFO; pi:PROCESS_INFORMATION; @@ -471,7 +478,6 @@ var DATA :array[0..MAX_PATH*2] of WideChar; end; LEN:ULONG; - R:DWORD; b:BOOL; begin Result:=0; @@ -479,12 +485,12 @@ begin FillChar(BUF,SizeOf(BUF),0); LEN:=SizeOf(BUF); - R:=NtQueryInformationProcess(NtCurrentProcess, - ProcessImageFileNameWin32, - @BUF, - LEN, - @LEN); - if (R<>0) then Exit; + Result:=NtQueryInformationProcess(NtCurrentProcess, + ProcessImageFileNameWin32, + @BUF, + LEN, + @LEN); + if (Result<>0) then Exit; si:=Default(TSTARTUPINFO); pi:=Default(PROCESS_INFORMATION); @@ -492,18 +498,27 @@ begin si.cb:=SizeOf(si); b:=CreateProcessW(PWideChar(@BUF.DATA),nil,nil,nil,False,CREATE_SUSPENDED,nil,nil,@si,@pi); - if not b then Exit; + if not b then Exit(-1); b:=AssignProcessToJobObject(NtFetchJob, pi.hProcess); + if not b then Exit(-1); - NtMoveStack(pi.hProcess,pi.hThread); - NtReserve(pi.hProcess); - NtCreateShared(pi.hProcess,proc,data,size); + Result:=NtMoveStack(pi.hProcess,pi.hThread); + if (Result<>0) then Exit; + + Result:=NtReserve(pi.hProcess); + if (Result<>0) then Exit; + + Result:=NtCreateShared(pi.hProcess,proc,data,size); + if (Result<>0) then Exit; + + Result:=NtResumeProcess(pi.hProcess); + if (Result<>0) then Exit; - NtResumeProcess(pi.hProcess); NtClose(pi.hThread); - Result:=pi.hProcess; + info.hProcess:=pi.hProcess; + info.fork_pid:=pi.dwProcessId; end; end. diff --git a/sys/sys_conf.pas b/sys/sys_conf.pas new file mode 100644 index 00000000..db9c5b0d --- /dev/null +++ b/sys/sys_conf.pas @@ -0,0 +1,450 @@ +unit sys_conf; + +{$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} + +interface + +uses + mqueue, + time, + kern_param, + vmount, + vfile, + vuio, + vnode, + sys_event, + vm, + sys_vm_object, + kern_mtx; + +const + //modeventtype + MOD_LOAD =0; + MOD_UNLOAD =1; + MOD_SHUTDOWN=2; + MOD_QUIESCE =3; + + SI_ETERNAL =$0001; { never destroyed } + SI_ALIAS =$0002; { carrier of alias name } + SI_NAMED =$0004; { make_dev _alias has been called } + SI_CHEAPCLONE=$0008; { can be removed_dev'ed when vnode reclaims } + SI_CHILD =$0010; { child of another struct cdev *} + SI_DEVOPEN =$0020; { opened by device } + SI_CONSOPEN =$0040; { opened by console } + SI_DUMPDEV =$0080; { is kernel dumpdev } + SI_CANDELETE =$0100; { can do BIO_DELETE } + SI_CLONELIST =$0200; { on a clone list } + SI_UNMAPPED =$0400; { can handle unmapped I/O } + +type + pp_cdev=^p_cdev; + p_cdev=^t_cdev; + t_cdev=packed record + si_mountpt :p_mount; + si_flags :DWORD; + _align1 :Integer; + si_atime :timespec; + si_ctime :timespec; + si_mtime :timespec; + si_uid :uid_t; + si_gid :gid_t; + si_mode :mode_t; + si_drv0 :Integer; + si_refcount :Integer; + _align2 :Integer; + si_list :LIST_ENTRY; //(cdev) + si_clone :LIST_ENTRY; //(cdev) + si_children :LIST_HEAD ; //(cdev) + si_siblings :LIST_ENTRY; //(cdev) + si_parent :p_cdev; + si_name :PChar; + si_drv1 :Pointer; + si_drv2 :Pointer; + si_devsw :Pointer; //cdevsw + si_iosize_max :Integer; { maximum I/O size (for physio &al) } + _align3 :Integer; + si_usecount :QWORD; + si_threadcount:QWORD; + si_snapdata :Pointer; //snapdata + __si_namebuf :array[0..SPECNAMELEN] of AnsiChar; + end; + + d_open_t =Function (dev:p_cdev;oflags,devtype:Integer):Integer; + d_fdopen_t =Function (dev:p_cdev;oflags:Integer;fp:p_file):Integer; + d_close_t =Function (dev:p_cdev;fflag,devtype:Integer):Integer; + d_strategy_t =Procedure(bp:Pointer);//bio + d_ioctl_t =Function (dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer; + + d_read_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; + d_write_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; + d_poll_t =Function (dev:p_cdev;events:Integer):Integer; + d_kqfilter_t =Function (dev:p_cdev;kn:p_knote):Integer; + d_mmap_t =Function (dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer; + d_mmap_single_t =Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer):Integer; + d_mmap_single2_t=Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer;maxprotp:p_vm_prot_t;flagsp:PInteger):Integer; + d_purge_t =Procedure(dev:p_cdev); + + dumper_t=Function( + _priv:Pointer ; { Private to the driver. } + _virtual:Pointer ; { Virtual (mapped) address. } + _physical:vm_offset_t; { Physical address of virtual. } + _offset:Int64 ; { Byte-offset to write at. } + _length:QWORD):Integer; { Number of bytes to dump. } + +const + { + * Types for d_flags. + } + D_TAPE=$0001; + D_DISK=$0002; + D_TTY =$0004; + D_MEM =$0008; + + D_TYPEMASK=$ffff; + + { + * Flags for d_flags which the drivers can set. + } + D_TRACKCLOSE =$00080000; { track all closes } + D_MMAP_ANON =$00100000; { special treatment in vm_mmap.c } + D_PSEUDO =$00200000; { make_dev() can return NULL } + D_NEEDGIANT =$00400000; { driver want Giant } + D_NEEDMINOR =$00800000; { driver uses clone_create() } + D_UNMAPPED_IO=$01000000; { d_strategy can accept unmapped IO } + + { + * Version numbers. + } + D_VERSION_00=$20011966; + D_VERSION_01=$17032005; { Add d_uid,gid,mode & kind } + D_VERSION_02=$28042009; { Add d_mmap_single } + D_VERSION_03=$17122009; { d_mmap takes memattr,vm_ooffset_t } + D_VERSION=D_VERSION_03; + + { + * Flags used for internal housekeeping + } + D_INIT =$80000000; { cdevsw initialized } + + { + * Character device switch table + } +type + pp_cdevsw=^p_cdevsw; + p_cdevsw=^t_cdevsw; + t_cdevsw=packed record + d_version :Integer; + d_flags :DWORD; + d_name :PChar; + d_open :d_open_t; + d_fdopen :d_fdopen_t; + d_close :d_close_t; + d_read :d_read_t; + d_write :d_write_t; + d_ioctl :d_ioctl_t; + d_poll :d_poll_t; + d_mmap :d_mmap_t; + d_strategy :d_strategy_t; + d_dump :dumper_t; + d_kqfilter :d_kqfilter_t; + d_purge :d_purge_t; + d_mmap_single :d_mmap_single_t; + d_mmap_single2:d_mmap_single2_t; + + d_spare0:array[0..1] of Integer; + d_spare1:array[0..2] of Pointer; + + { These fields should not be messed with by drivers } + d_devs:Pointer; //cdev + d_spare2:array[0..1] of Integer; + d_gianttrick:p_cdevsw; + d_postfree_list:SLIST_ENTRY; //cdevsw + end; + +const + MAKEDEV_REF =$01; + MAKEDEV_WHTOUT =$02; + MAKEDEV_NOWAIT =$04; + MAKEDEV_WAITOK =$08; + MAKEDEV_ETERNAL =$10; + MAKEDEV_CHECKNAME=$20; + + UID_ROOT =0; + UID_BIN =3; + UID_UUCP =66; + UID_NOBODY =65534; + + GID_WHEEL =0; + GID_KMEM =2; + GID_TTY =4; + GID_OPERATOR=5; + GID_BIN =7; + GID_GAMES =13; + GID_DIALER =68; + GID_NOBODY =65534; + +var + devmtx:mtx; + + cdevp_free_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@cdevp_free_list.tqh_first); + cdevsw_gt_post_list:SLIST_HEAD=(slh_first:nil); + +type + cdevpriv_dtr_t=Procedure(data:Pointer); + +function devfs_get_cdevpriv(datap:PPointer):Integer; external; +function devfs_set_cdevpriv(priv:Pointer;priv_dtr:cdevpriv_dtr_t):Integer; external; +procedure devfs_clear_cdevpriv(); external; +procedure devfs_fpdrop(fp:p_file); external; + +type + ino_t=Integer; + +function devfs_alloc_cdp_inode():ino_t; external; +procedure devfs_free_cdp_inode(ino:ino_t); external; + +procedure dev_lock(); external; +procedure dev_unlock(); external; +procedure dev_ref(dev:p_cdev); external; +procedure dev_refl(dev:p_cdev); external; +procedure dev_rel(dev:p_cdev); external; + +function dev_refthread(dev:p_cdev;ref:PInteger):p_cdevsw; external; +function devvn_refthread(vp:p_vnode;devp:pp_cdev;ref:PInteger):p_cdevsw; external; +procedure dev_relthread(dev:p_cdev;ref:Integer); external; + +procedure destroy_dev(dev:p_cdev); external; + +function dev2unit(d:p_cdev):Integer; +function devtoname(dev:p_cdev):PChar; + +function make_dev_credv(flags:Integer; + dres:pp_cdev; + devsw:p_cdevsw; + _unit:Integer; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):Integer; register; external; + +function make_dev(devsw:p_cdevsw; + _unit:Integer; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):p_cdev; register; + +function make_dev_cred(devsw:p_cdevsw; + _unit:Integer; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):p_cdev; register; + +function make_dev_credf(flags:Integer; + devsw:p_cdevsw; + _unit:Integer; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):p_cdev; register; + +function make_dev_p(flags:Integer; + cdev:pp_cdev; + devsw:p_cdevsw; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):Integer; register; + +function make_dev_alias_v(flags:Integer; + cdev:pp_cdev; + pdev:p_cdev; + fmt:PChar; + const Args:Array of const):Integer; register; external; + +function make_dev_alias(pdev:p_cdev; + fmt:PChar; + const Args:Array of const):p_cdev; register; + +function make_dev_alias_p(flags:Integer; + cdev:pp_cdev; + pdev:p_cdev; + fmt:PChar; + const Args:Array of const):Integer; register; + +function make_dev_physpath_alias(flags:Integer; + cdev:pp_cdev; + pdev,old_alias:p_cdev; + physpath:PChar):Integer; external; + +function _nullop():Integer; +function _eopnotsupp():Integer; +function _enxio():Integer; +function _enodev():Integer; +function _einval():Integer; + +implementation + +uses + errno; + +function dev2unit(d:p_cdev):Integer; inline; +begin + Result:=d^.si_drv0; +end; + +function devtoname(dev:p_cdev):PChar; inline; +begin + Result:=dev^.si_name; +end; + +function _nullop():Integer; +begin + Exit(0); +end; + +function _eopnotsupp():Integer; +begin + Exit(EOPNOTSUPP); +end; + +function _enxio():Integer; +begin + Exit(ENXIO); +end; + +function _enodev():Integer; +begin + Exit(ENODEV); +end; + +function _einval():Integer; +begin + Exit(EINVAL); +end; + +function make_dev(devsw:p_cdevsw; + _unit:Integer; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):p_cdev; register; public; +var + dev:p_cdev; + res:Integer; +begin + res:=make_dev_credv(0, @dev, devsw, _unit, uid, gid, mode, fmt, Args); + + Assert((res=0) and (dev<>nil),'make_dev: failed make_dev_credv (error=%d)'); + + if (res=0) then + Exit(dev) + else + Exit(nil); +end; + +function make_dev_cred(devsw:p_cdevsw; + _unit:Integer; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):p_cdev; register; public; +var + dev:p_cdev; + res:Integer; +begin + res:=make_dev_credv(0, @dev, devsw, _unit, uid, gid, mode, fmt, Args); + + Assert((res=0) and (dev<>nil),'make_dev_cred: failed make_dev_credv (error=%d)'); + + if (res=0) then + Exit(dev) + else + Exit(nil); +end; + +function make_dev_credf(flags:Integer; + devsw:p_cdevsw; + _unit:Integer; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):p_cdev; register; public; +var + dev:p_cdev; + res:Integer; +begin + res:=make_dev_credv(flags, @dev, devsw, _unit, uid, gid, mode, fmt, Args); + + Assert((((flags and MAKEDEV_NOWAIT)<>0) and (res=ENOMEM)) or + (((flags and MAKEDEV_CHECKNAME)<>0) and (res<>ENOMEM)) or + (res=0),'make_dev_credf: failed make_dev_credv (error=%d)'); + + if (res=0) then + Exit(dev) + else + Exit(nil); +end; + +function make_dev_p(flags:Integer; + cdev:pp_cdev; + devsw:p_cdevsw; + uid:uid_t; + gid:gid_t; + mode:Integer; + fmt:PChar; + const Args:Array of const):Integer; register; public; +var + res:Integer; +begin + res:=make_dev_credv(flags, cdev, devsw, 0, uid, gid, mode, fmt, Args); + + Assert((((flags and MAKEDEV_NOWAIT)<>0) and (res=ENOMEM)) or + (((flags and MAKEDEV_CHECKNAME)<>0) and (res<>ENOMEM)) or + (res=0),'make_dev_p: failed make_dev_credv (error=%d)'); + + Exit(res); +end; + +function make_dev_alias(pdev:p_cdev; + fmt:PChar; + const Args:Array of const):p_cdev; register; public; +var + dev:p_cdev; + res:Integer; +begin + res:=make_dev_alias_v(MAKEDEV_WAITOK, @dev, pdev, fmt, Args); + + Assert((res=0) and (dev<>nil),'make_dev_alias: failed make_dev_alias_v (error=%d)'); + + if (res=0) then + Exit(dev) + else + Exit(nil); +end; + +function make_dev_alias_p(flags:Integer; + cdev:pp_cdev; + pdev:p_cdev; + fmt:PChar; + const Args:Array of const):Integer; register; public; +var + res:Integer; +begin + res:=make_dev_alias_v(flags, cdev, pdev, fmt, Args); + + Exit(res); +end; + +end. + diff --git a/sys/sys_event.pas b/sys/sys_event.pas index 75858e90..9f3db94b 100644 --- a/sys/sys_event.pas +++ b/sys/sys_event.pas @@ -6,6 +6,7 @@ unit sys_event; interface uses + time, mqueue; const @@ -39,6 +40,7 @@ const EV_DELETE =$0002; // delete event from kq EV_ENABLE =$0004; // enable event EV_DISABLE =$0008; // disable event (not reported) + EV_ACTION =EV_ADD or EV_DELETE or EV_ENABLE or EV_DISABLE; // flags EV_ONESHOT =$0010; // only report one occurrence @@ -227,6 +229,8 @@ type end; {$IF sizeof(t_kevent_copyops)<>24}{$STOP sizeof(t_kevent_copyops)<>24}{$ENDIF} + t_kqueue_wakeup_cb=procedure(data:Pointer); + function knote_alloc():p_knote; external; procedure knote_free(kn:p_knote); external; @@ -243,6 +247,25 @@ procedure knlist_init_mtx(knl:p_knlist;lock:Pointer); external; procedure knlist_destroy (knl:p_knlist); external; procedure knlist_cleardel(knl:p_knlist;islocked,killkn:Integer); external; +function kern_kqueue2(name:PAnsiChar; + w_cb:t_kqueue_wakeup_cb; + data:Pointer):Pointer; external; + +procedure kqueue_close2(kq:Pointer); external; + +function kern_kevent2(kq :Pointer; + changelist:p_kevent; + nchanges :Integer; + eventlist :p_kevent; + nevents :Integer; + timeout :p_timespec; + p_ncount :PInteger):Integer; external; + +function kqueue_add_filteropts(filt:Integer;filtops:p_filterops):Integer; external; +function kqueue_del_filteropts(filt:Integer):Integer; external; +function kqfd_register(fd:Integer;kev:p_kevent):Integer; external; +procedure kqueue_deregister(filter:SmallInt;pid,ident:PtrUint); external; + // procedure KNOTE_LOCKED (list:p_knlist;hint:QWORD); diff --git a/sys/sys_eventvar.pas b/sys/sys_eventvar.pas index 160c424e..f527c80a 100644 --- a/sys/sys_eventvar.pas +++ b/sys/sys_eventvar.pas @@ -44,6 +44,8 @@ type kq_knhashmask:QWORD; // size of knhash kq_knhash :p_klist; // hash table for knotes //kq_task:task; + kq_wakeup :t_kqueue_wakeup_cb; + kq_data :Pointer; kq_name :t_kq_name; end; diff --git a/sys/sys_sysinit.pas b/sys/sys_sysinit.pas index f1c80f79..72e1b9b8 100644 --- a/sys/sys_sysinit.pas +++ b/sys/sys_sysinit.pas @@ -12,6 +12,9 @@ implementation uses init_sysent, //compile spec kern_rtprio, //compile spec + kern_conf, //compile spec + devfs_vnops, //compile spec + devfs_rule, //compile spec time, kern_time, subr_sleepqueue, @@ -42,7 +45,7 @@ uses ufs, kern_descrip, vfs_mountroot, - kern_conf, + sys_conf, dev_null, dev_tty, dev_dmem, diff --git a/sys/vfs/kern_conf.pas b/sys/vfs/kern_conf.pas index 5e6b68c9..cda87876 100644 --- a/sys/vfs/kern_conf.pas +++ b/sys/vfs/kern_conf.pas @@ -7,8 +7,8 @@ interface uses mqueue, + sys_conf, kern_param, - sys_event, vmount, vfile, vuio, @@ -18,274 +18,12 @@ uses sys_vm_object, kern_mtx; -const - //modeventtype - MOD_LOAD =0; - MOD_UNLOAD =1; - MOD_SHUTDOWN=2; - MOD_QUIESCE =3; - - SI_ETERNAL =$0001; { never destroyed } - SI_ALIAS =$0002; { carrier of alias name } - SI_NAMED =$0004; { make_dev _alias has been called } - SI_CHEAPCLONE=$0008; { can be removed_dev'ed when vnode reclaims } - SI_CHILD =$0010; { child of another struct cdev *} - SI_DEVOPEN =$0020; { opened by device } - SI_CONSOPEN =$0040; { opened by console } - SI_DUMPDEV =$0080; { is kernel dumpdev } - SI_CANDELETE =$0100; { can do BIO_DELETE } - SI_CLONELIST =$0200; { on a clone list } - SI_UNMAPPED =$0400; { can handle unmapped I/O } - -type - pp_cdev=^p_cdev; - p_cdev=^t_cdev; - t_cdev=packed record - si_mountpt :p_mount; - si_flags :DWORD; - _align1 :Integer; - si_atime :timespec; - si_ctime :timespec; - si_mtime :timespec; - si_uid :uid_t; - si_gid :gid_t; - si_mode :mode_t; - si_drv0 :Integer; - si_refcount :Integer; - _align2 :Integer; - si_list :LIST_ENTRY; //(cdev) - si_clone :LIST_ENTRY; //(cdev) - si_children :LIST_HEAD ; //(cdev) - si_siblings :LIST_ENTRY; //(cdev) - si_parent :p_cdev; - si_name :PChar; - si_drv1 :Pointer; - si_drv2 :Pointer; - si_devsw :Pointer; //cdevsw - si_iosize_max :Integer; { maximum I/O size (for physio &al) } - _align3 :Integer; - si_usecount :QWORD; - si_threadcount:QWORD; - si_snapdata :Pointer; //snapdata - __si_namebuf :array[0..SPECNAMELEN] of AnsiChar; - end; - - d_open_t =Function (dev:p_cdev;oflags,devtype:Integer):Integer; - d_fdopen_t =Function (dev:p_cdev;oflags:Integer;fp:p_file):Integer; - d_close_t =Function (dev:p_cdev;fflag,devtype:Integer):Integer; - d_strategy_t =Procedure(bp:Pointer);//bio - d_ioctl_t =Function (dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer; - - d_read_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; - d_write_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; - d_poll_t =Function (dev:p_cdev;events:Integer):Integer; - d_kqfilter_t =Function (dev:p_cdev;kn:p_knote):Integer; - d_mmap_t =Function (dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer; - d_mmap_single_t =Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer):Integer; - d_mmap_single2_t=Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer;maxprotp:p_vm_prot_t;flagsp:PInteger):Integer; - d_purge_t =Procedure(dev:p_cdev); - - dumper_t=Function( - _priv:Pointer ; { Private to the driver. } - _virtual:Pointer ; { Virtual (mapped) address. } - _physical:vm_offset_t; { Physical address of virtual. } - _offset:Int64 ; { Byte-offset to write at. } - _length:QWORD):Integer; { Number of bytes to dump. } - -const - { - * Types for d_flags. - } - D_TAPE=$0001; - D_DISK=$0002; - D_TTY =$0004; - D_MEM =$0008; - - D_TYPEMASK=$ffff; - - { - * Flags for d_flags which the drivers can set. - } - D_TRACKCLOSE =$00080000; { track all closes } - D_MMAP_ANON =$00100000; { special treatment in vm_mmap.c } - D_PSEUDO =$00200000; { make_dev() can return NULL } - D_NEEDGIANT =$00400000; { driver want Giant } - D_NEEDMINOR =$00800000; { driver uses clone_create() } - D_UNMAPPED_IO=$01000000; { d_strategy can accept unmapped IO } - - { - * Version numbers. - } - D_VERSION_00=$20011966; - D_VERSION_01=$17032005; { Add d_uid,gid,mode & kind } - D_VERSION_02=$28042009; { Add d_mmap_single } - D_VERSION_03=$17122009; { d_mmap takes memattr,vm_ooffset_t } - D_VERSION=D_VERSION_03; - - { - * Flags used for internal housekeeping - } - D_INIT =$80000000; { cdevsw initialized } - - { - * Character device switch table - } -type - pp_cdevsw=^p_cdevsw; - p_cdevsw=^t_cdevsw; - t_cdevsw=packed record - d_version :Integer; - d_flags :DWORD; - d_name :PChar; - d_open :d_open_t; - d_fdopen :d_fdopen_t; - d_close :d_close_t; - d_read :d_read_t; - d_write :d_write_t; - d_ioctl :d_ioctl_t; - d_poll :d_poll_t; - d_mmap :d_mmap_t; - d_strategy :d_strategy_t; - d_dump :dumper_t; - d_kqfilter :d_kqfilter_t; - d_purge :d_purge_t; - d_mmap_single :d_mmap_single_t; - d_mmap_single2:d_mmap_single2_t; - - d_spare0:array[0..1] of Integer; - d_spare1:array[0..2] of Pointer; - - { These fields should not be messed with by drivers } - d_devs:Pointer; //cdev - d_spare2:array[0..1] of Integer; - d_gianttrick:p_cdevsw; - d_postfree_list:SLIST_ENTRY; //cdevsw - end; - -const - MAKEDEV_REF =$01; - MAKEDEV_WHTOUT =$02; - MAKEDEV_NOWAIT =$04; - MAKEDEV_WAITOK =$08; - MAKEDEV_ETERNAL =$10; - MAKEDEV_CHECKNAME=$20; - - UID_ROOT =0; - UID_BIN =3; - UID_UUCP =66; - UID_NOBODY =65534; - - GID_WHEEL =0; - GID_KMEM =2; - GID_TTY =4; - GID_OPERATOR=5; - GID_BIN =7; - GID_GAMES =13; - GID_DIALER =68; - GID_NOBODY =65534; - -function dev2unit(d:p_cdev):Integer; inline; -function devtoname(dev:p_cdev):PChar; - -type - cdevpriv_dtr_t=Procedure(data:Pointer); - -var - devmtx:mtx; - - cdevp_free_list:TAILQ_HEAD=(tqh_first:nil;tqh_last:@cdevp_free_list.tqh_first); - cdevsw_gt_post_list:SLIST_HEAD=(slh_first:nil); - -function _nullop():Integer; -function _eopnotsupp():Integer; -function _enxio():Integer; -function _enodev():Integer; -function _einval():Integer; - -procedure dev_lock(); -procedure dev_unlock(); -procedure dev_ref(dev:p_cdev); -procedure dev_refl(dev:p_cdev); -procedure dev_rel(dev:p_cdev); - -function dev_refthread(dev:p_cdev;ref:PInteger):p_cdevsw; -function devvn_refthread(vp:p_vnode;devp:pp_cdev;ref:PInteger):p_cdevsw; -procedure dev_relthread(dev:p_cdev;ref:Integer); - -procedure destroy_dev(dev:p_cdev); - -function make_dev_credv(flags:Integer; - dres:pp_cdev; - devsw:p_cdevsw; - _unit:Integer; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):Integer; register; - -function make_dev(devsw:p_cdevsw; - _unit:Integer; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):p_cdev; register; - -function make_dev_cred(devsw:p_cdevsw; - _unit:Integer; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):p_cdev; register; - -function make_dev_credf(flags:Integer; - devsw:p_cdevsw; - _unit:Integer; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):p_cdev; register; - -function make_dev_p(flags:Integer; - cdev:pp_cdev; - devsw:p_cdevsw; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):Integer; register; - -function make_dev_alias_v(flags:Integer; - cdev:pp_cdev; - pdev:p_cdev; - fmt:PChar; - const Args:Array of const):Integer; register; - -function make_dev_alias(pdev:p_cdev; - fmt:PChar; - const Args:Array of const):p_cdev; register; - -function make_dev_alias_p(flags:Integer; - cdev:pp_cdev; - pdev:p_cdev; - fmt:PChar; - const Args:Array of const):Integer; register; - -function make_dev_physpath_alias(flags:Integer; - cdev:pp_cdev; - pdev,old_alias:p_cdev; - physpath:PChar):Integer; - implementation uses sysutils, errno, - devfs, - devfs_vnops, + devfs_int, vsys_generic, kern_synch; @@ -304,30 +42,30 @@ begin Result:=c-ptruint(@p_cdev_priv(nil)^.cdp_c); end; -procedure dev_lock(); +procedure dev_lock(); public; begin mtx_lock(devmtx); end; -procedure dev_unlock(); +procedure dev_unlock(); public; begin mtx_unlock(devmtx); end; -procedure dev_ref(dev:p_cdev); +procedure dev_ref(dev:p_cdev); public; begin mtx_lock(devmtx); Inc(dev^.si_refcount); mtx_unlock(devmtx); end; -procedure dev_refl(dev:p_cdev); +procedure dev_refl(dev:p_cdev); public; begin mtx_assert(devmtx); Inc(dev^.si_refcount); end; -procedure dev_rel(dev:p_cdev); +procedure dev_rel(dev:p_cdev); public; var flag:Integer; begin @@ -350,7 +88,7 @@ begin end; end; -function dev_refthread(dev:p_cdev;ref:PInteger):p_cdevsw; +function dev_refthread(dev:p_cdev;ref:PInteger):p_cdevsw; public; var csw:p_cdevsw; cdp:p_cdev_priv; @@ -375,7 +113,7 @@ begin Exit(csw); end; -function devvn_refthread(vp:p_vnode;devp:pp_cdev;ref:PInteger):p_cdevsw; +function devvn_refthread(vp:p_vnode;devp:pp_cdev;ref:PInteger):p_cdevsw; public; var csw:p_cdevsw; cdp:p_cdev_priv; @@ -418,7 +156,7 @@ begin Exit(csw); end; -procedure dev_relthread(dev:p_cdev;ref:Integer); +procedure dev_relthread(dev:p_cdev;ref:Integer); public; begin if (ref=0) then Exit; dev_lock(); @@ -486,31 +224,6 @@ begin SLIST_INSERT_HEAD(@cdevsw_gt_post_list,csw,@csw^.d_postfree_list); end; -function _nullop():Integer; -begin - Exit(0); -end; - -function _eopnotsupp():Integer; -begin - Exit(EOPNOTSUPP); -end; - -function _enxio():Integer; -begin - Exit(ENXIO); -end; - -function _enodev():Integer; -begin - Exit(ENODEV); -end; - -function _einval():Integer; -begin - Exit(EINVAL); -end; - procedure dead_strategy(bp:Pointer); begin //biofinish(bp, nil, ENXIO); @@ -1000,7 +713,7 @@ function make_dev_credv(flags:Integer; gid:gid_t; mode:Integer; fmt:PChar; - const Args:Array of const):Integer; register; + const Args:Array of const):Integer; register; public name 'make_dev_credv'; var dev,dev_new:p_cdev; res:Integer; @@ -1074,92 +787,6 @@ begin Exit(0); end; -function make_dev(devsw:p_cdevsw; - _unit:Integer; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):p_cdev; register; -var - dev:p_cdev; - res:Integer; -begin - res:=make_dev_credv(0, @dev, devsw, _unit, uid, gid, mode, fmt, Args); - - Assert((res=0) and (dev<>nil),'make_dev: failed make_dev_credv (error=%d)'); - - if (res=0) then - Exit(dev) - else - Exit(nil); -end; - -function make_dev_cred(devsw:p_cdevsw; - _unit:Integer; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):p_cdev; register; -var - dev:p_cdev; - res:Integer; -begin - res:=make_dev_credv(0, @dev, devsw, _unit, uid, gid, mode, fmt, Args); - - Assert((res=0) and (dev<>nil),'make_dev_cred: failed make_dev_credv (error=%d)'); - - if (res=0) then - Exit(dev) - else - Exit(nil); -end; - -function make_dev_credf(flags:Integer; - devsw:p_cdevsw; - _unit:Integer; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):p_cdev; register; -var - dev:p_cdev; - res:Integer; -begin - res:=make_dev_credv(flags, @dev, devsw, _unit, uid, gid, mode, fmt, Args); - - Assert((((flags and MAKEDEV_NOWAIT)<>0) and (res=ENOMEM)) or - (((flags and MAKEDEV_CHECKNAME)<>0) and (res<>ENOMEM)) or - (res=0),'make_dev_credf: failed make_dev_credv (error=%d)'); - - if (res=0) then - Exit(dev) - else - Exit(nil); -end; - -function make_dev_p(flags:Integer; - cdev:pp_cdev; - devsw:p_cdevsw; - uid:uid_t; - gid:gid_t; - mode:Integer; - fmt:PChar; - const Args:Array of const):Integer; register; -var - res:Integer; -begin - res:=make_dev_credv(flags, cdev, devsw, 0, uid, gid, mode, fmt, Args); - - Assert((((flags and MAKEDEV_NOWAIT)<>0) and (res=ENOMEM)) or - (((flags and MAKEDEV_CHECKNAME)<>0) and (res<>ENOMEM)) or - (res=0),'make_dev_p: failed make_dev_credv (error=%d)'); - - Exit(res); -end; - procedure dev_dependsl(pdev,cdev:p_cdev); begin cdev^.si_parent:=pdev; @@ -1178,7 +805,7 @@ function make_dev_alias_v(flags:Integer; cdev:pp_cdev; pdev:p_cdev; fmt:PChar; - const Args:Array of const):Integer; register; + const Args:Array of const):Integer; register; public name 'make_dev_alias_v'; var dev:p_cdev; error:Integer; @@ -1217,40 +844,10 @@ begin Exit(0); end; -function make_dev_alias(pdev:p_cdev; - fmt:PChar; - const Args:Array of const):p_cdev; register; -var - dev:p_cdev; - res:Integer; -begin - res:=make_dev_alias_v(MAKEDEV_WAITOK, @dev, pdev, fmt, Args); - - Assert((res=0) and (dev<>nil),'make_dev_alias: failed make_dev_alias_v (error=%d)'); - - if (res=0) then - Exit(dev) - else - Exit(nil); -end; - -function make_dev_alias_p(flags:Integer; - cdev:pp_cdev; - pdev:p_cdev; - fmt:PChar; - const Args:Array of const):Integer; register; -var - res:Integer; -begin - res:=make_dev_alias_v(flags, cdev, pdev, fmt, Args); - - Exit(res); -end; - function make_dev_physpath_alias(flags:Integer; cdev:pp_cdev; pdev,old_alias:p_cdev; - physpath:PChar):Integer; + physpath:PChar):Integer; public; label _ret, _out; @@ -1473,7 +1070,7 @@ begin dev_unlock(); end; -procedure destroy_dev(dev:p_cdev); +procedure destroy_dev(dev:p_cdev); public; begin dev_lock(); destroy_devl(dev); diff --git a/sys/vfs/kern_descrip.pas b/sys/vfs/kern_descrip.pas index 1e2b21f8..933f65d2 100644 --- a/sys/vfs/kern_descrip.pas +++ b/sys/vfs/kern_descrip.pas @@ -137,7 +137,7 @@ uses sys_resource, kern_resource, kern_mtx, - kern_conf; + sys_conf; // @@ -809,7 +809,7 @@ begin Exit(0); end; -function kern_close(fd:Integer):Integer; +function kern_close(fd:Integer):Integer; public; var fp,fp_object:p_file; begin diff --git a/sys/vfs/vfs_subr.pas b/sys/vfs/vfs_subr.pas index eb81303b..3b227666 100644 --- a/sys/vfs/vfs_subr.pas +++ b/sys/vfs/vfs_subr.pas @@ -193,7 +193,7 @@ uses sys_vm_object, vsys_generic, rtprio, - kern_conf; + sys_conf; // diff --git a/sys/vm/device_pager.pas b/sys/vm/device_pager.pas index 269bb9bd..d3b0133b 100644 --- a/sys/vm/device_pager.pas +++ b/sys/vm/device_pager.pas @@ -23,7 +23,7 @@ uses errno, vmparam, vm_pmap, - kern_conf; + sys_conf; function OFF_TO_IDX(x:QWORD):DWORD; inline; begin diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas index c13b54ec..5bddf387 100644 --- a/sys/vm/vm_mmap.pas +++ b/sys/vm/vm_mmap.pas @@ -66,7 +66,7 @@ uses vnode, vfs_subr, vnode_if, - kern_conf, + sys_conf, vm_pager; function vm_mmap_cdev(objsize :vm_size_t;