mirror of https://github.com/red-prig/fpPS4.git
354 lines
12 KiB
Plaintext
354 lines
12 KiB
Plaintext
unit sys_event;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
time,
|
|
mqueue;
|
|
|
|
const
|
|
EVFILT_READ =(-1);
|
|
EVFILT_WRITE =(-2);
|
|
EVFILT_AIO =(-3); // attached to aio requests
|
|
EVFILT_VNODE =(-4); // attached to vnodes
|
|
EVFILT_PROC =(-5); // attached to struct proc
|
|
EVFILT_SIGNAL =(-6); // attached to struct proc
|
|
EVFILT_TIMER =(-7); // timers
|
|
//EVFILT_NETDEV =(-8); no longer supported
|
|
EVFILT_FS =(-9); // filesystem events
|
|
EVFILT_LIO =(-10); // attached to lio requests
|
|
EVFILT_USER =(-11); // User events
|
|
EVFILT_POLLING =(-12);
|
|
EVFILT_DISPLAY =(-13); // dev/dce
|
|
EVFILT_GRAPHICS_CORE =(-14); // dev/gc
|
|
EVFILT_HRTIMER =(-15); // High resolution timers
|
|
EVFILT_UVD_TRAP =(-16);
|
|
EVFILT_VCE_TRAP =(-17);
|
|
EVFILT_SDMA_TRAP =(-18);
|
|
EVFILT_REG_EV =(-19);
|
|
EVFILT_GPU_EXCEPTION =(-20);
|
|
EVFILT_GPU_SYSTEM_EXCEPTION=(-21);
|
|
EVFILT_GPU_DBGGC_EV =(-22);
|
|
EVFILT_CPUMODE =(-23);
|
|
EVFILT_SYSCOUNT =(23);
|
|
|
|
// actions
|
|
EV_ADD =$0001; // add event to kq (implies enable)
|
|
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
|
|
EV_CLEAR =$0020; // clear event state after reporting
|
|
EV_RECEIPT =$0040; // force EV_ERROR on success, data=0
|
|
EV_DISPATCH =$0080; // disable event after reporting
|
|
|
|
EV_SYSFLAGS =$F000; // reserved by system
|
|
EV_DROP =$1000; // note should be dropped
|
|
EV_FLAG1 =$2000; // filter-specific flag
|
|
|
|
// returned values
|
|
EV_EOF =$8000; // EOF detected
|
|
EV_ERROR =$4000; // error, data contains errno
|
|
|
|
//data/hint flags/masks for EVFILT_USER, shared with userspace
|
|
NOTE_FFNOP =$00000000; // ignore input fflags
|
|
NOTE_FFAND =$40000000; // AND fflags
|
|
NOTE_FFOR =$80000000; // OR fflags
|
|
NOTE_FFCOPY =$c0000000; // copy fflags
|
|
NOTE_FFCTRLMASK=$c0000000; // masks for operations
|
|
NOTE_FFLAGSMASK=$00ffffff;
|
|
|
|
NOTE_TRIGGER =$01000000; // Cause the event to be triggered for output.
|
|
|
|
//data/hint flags for EVFILT_{READ|WRITE}, shared with userspace
|
|
NOTE_LOWAT =$0001; // low water mark
|
|
|
|
NOTE_DELETE =$0001; // vnode was removed
|
|
NOTE_WRITE =$0002; // data contents changed
|
|
NOTE_EXTEND =$0004; // size increased
|
|
NOTE_ATTRIB =$0008; // attributes changed
|
|
NOTE_LINK =$0010; // link count changed
|
|
NOTE_RENAME =$0020; // vnode was renamed
|
|
NOTE_REVOKE =$0040; // vnode access was revoked
|
|
|
|
//data/hint flags for EVFILT_PROC, shared with userspace
|
|
NOTE_EXIT =$80000000; // process exited
|
|
NOTE_FORK =$40000000; // process forked
|
|
NOTE_EXEC =$20000000; // process exec'd
|
|
NOTE_PCTRLMASK=$f0000000; // mask for hint bits
|
|
NOTE_PDATAMASK=$000fffff; // mask for pid
|
|
|
|
// additional flags for EVFILT_PROC
|
|
NOTE_TRACK =$00000001; // follow across forks
|
|
NOTE_TRACKERR=$00000002; // could not track child
|
|
NOTE_CHILD =$00000004; // am a child process
|
|
|
|
// flags for EVFILT_POLLING
|
|
NOTE_POLLING_EQUAL=$00000001; // trigger when var == data
|
|
NOTE_POLLING_LESS =$00000002; // trigger when var < data
|
|
NOTE_POLLING_NOT =$00000004; // negate trigger condition
|
|
NOTE_POLLING_COND =$00000007;
|
|
NOTE_POLLING_64BIT=$00000008; // watch a 64-bit variable
|
|
|
|
//Flags for knote call
|
|
KNF_LISTLOCKED=$0001; // knlist is locked
|
|
KNF_NOKQLOCK =$0002; // do not keep KQ_LOCK
|
|
|
|
{
|
|
* Flag indicating hint is a signal. Used by EVFILT_SIGNAL, and also
|
|
* shared by EVFILT_PROC (all knotes attached to p->p_klist)
|
|
}
|
|
NOTE_SIGNAL=$08000000;
|
|
|
|
//Hint values for the optional f_touch event filter
|
|
EVENT_REGISTER=1;
|
|
EVENT_PROCESS =2;
|
|
|
|
//kn_status
|
|
KN_ACTIVE =$001; // event has been triggered
|
|
KN_QUEUED =$002; // event is on queue
|
|
KN_DISABLED =$004; // event is disabled
|
|
KN_DETACHED =$008; // knote is detached
|
|
KN_INFLUX =$010; // knote is in flux
|
|
KN_MARKER =$020; // ignore this knote
|
|
KN_KQUEUE =$040; // this knote belongs to a kq
|
|
KN_HASKQLOCK=$080; // for _inevent
|
|
KN_SCAN =$100; // flux set in kqueue_scan()
|
|
|
|
//sce
|
|
SCE_KERNEL_EVFILT_TIMER =EVFILT_TIMER ;
|
|
SCE_KERNEL_EVFILT_READ =EVFILT_READ ;
|
|
SCE_KERNEL_EVFILT_WRITE =EVFILT_WRITE ;
|
|
SCE_KERNEL_EVFILT_USER =EVFILT_USER ;
|
|
SCE_KERNEL_EVFILT_FILE =EVFILT_VNODE ;
|
|
SCE_KERNEL_EVFILT_GNM =EVFILT_GRAPHICS_CORE;
|
|
SCE_KERNEL_EVFILT_VIDEO_OUT =EVFILT_DISPLAY ;
|
|
SCE_KERNEL_EVFILT_HRTIMER =EVFILT_HRTIMER ;
|
|
|
|
SCE_KERNEL_EVNOTE_DELETE =NOTE_DELETE ;
|
|
SCE_KERNEL_EVNOTE_WRITE =NOTE_WRITE ;
|
|
SCE_KERNEL_EVNOTE_EXTEND =NOTE_EXTEND ;
|
|
SCE_KERNEL_EVNOTE_ATTRIB =NOTE_ATTRIB ;
|
|
SCE_KERNEL_EVNOTE_RENAME =NOTE_RENAME ;
|
|
SCE_KERNEL_EVNOTE_REVOKE =NOTE_REVOKE ;
|
|
|
|
SCE_KERNEL_EVFLAG_EOF =EV_EOF ;
|
|
SCE_KERNEL_EVFLAG_ERROR =EV_ERROR ;
|
|
|
|
SCE_VIDEO_OUT_EVENT_FLIP =0; //Flip completion event
|
|
SCE_VIDEO_OUT_EVENT_VBLANK =1; //Vblank event
|
|
SCE_VIDEO_OUT_EVENT_PRE_VBLANK_START=2; //PreVblankStart event
|
|
|
|
type
|
|
p_kevent=^t_kevent;
|
|
t_kevent=packed record
|
|
ident :PtrUint; // identifier for this event
|
|
filter:SmallInt; // filter for event
|
|
flags :Word; // action flags for kqueue
|
|
fflags:DWORD; // filter flag value
|
|
data :Ptrint; // filter data value
|
|
udata :Pointer; // opaque user data identifier
|
|
end;
|
|
{$IF sizeof(t_kevent)<>32}{$STOP sizeof(t_kevent)<>32}{$ENDIF}
|
|
|
|
pSceKernelEvent=^SceKernelEvent;
|
|
SceKernelEvent=t_kevent;
|
|
|
|
p_knote=^t_knote;
|
|
|
|
p_klist=^t_klist;
|
|
t_klist =SLIST_HEAD; //knote
|
|
|
|
p_kqlist=^t_kqlist;
|
|
t_kqlist=SLIST_HEAD; //kqueue
|
|
|
|
p_knlist=^t_knlist;
|
|
t_knlist=packed record
|
|
kl_list :t_klist;
|
|
kl_lock :procedure(arg:Pointer); // lock function
|
|
kl_unlock :procedure(arg:Pointer);
|
|
kl_assert_locked :procedure(arg:Pointer);
|
|
kl_assert_unlocked:procedure(arg:Pointer);
|
|
kl_lockarg :Pointer; // argument passed to kl_lockf()
|
|
end;
|
|
{$IF sizeof(t_knlist)<>48}{$STOP sizeof(t_knlist)<>48}{$ENDIF}
|
|
|
|
p_filterops=^t_filterops;
|
|
t_filterops=packed object
|
|
f_isfd :Integer; // true if ident == filedescriptor
|
|
_align :Integer;
|
|
f_attach:function (kn:p_knote):Integer;
|
|
f_detach:procedure(kn:p_knote);
|
|
f_event :function (kn:p_knote;hint:QWORD):Integer;
|
|
f_touch :procedure(kn:p_knote;kev:p_kevent;_type:QWORD);
|
|
end;
|
|
{$IF sizeof(t_filterops)<>40}{$STOP sizeof(t_filterops)<>40}{$ENDIF}
|
|
|
|
t_knote=packed object
|
|
kn_link :SLIST_ENTRY; // (knote) for kq
|
|
kn_selnext:SLIST_ENTRY; // (knote) for struct selinfo
|
|
kn_knlist :p_knlist; // f_attach populated
|
|
kn_tqe :TAILQ_ENTRY; // (knote)
|
|
kn_kq :Pointer; // (kqueue) which queue we are on
|
|
kn_kevent :t_kevent;
|
|
kn_status :Integer; // protected by kq lock
|
|
kn_sfflags:Integer; // saved filter flags
|
|
kn_sdata :Ptrint; // saved data field
|
|
kn_ptr :packed record
|
|
case Byte of
|
|
0:(p_fp :Pointer); // (file) file data pointer
|
|
1:(p_proc:Pointer); // (proc) proc pointer
|
|
2:(p_aio :Pointer); // (aiocblist) AIO job pointer
|
|
3:(p_lio :Pointer); // (aioliojob) LIO job pointer
|
|
end;
|
|
kn_fop :p_filterops;
|
|
kn_hook :Pointer;
|
|
kn_hookid :Integer;
|
|
_align :Integer;
|
|
//
|
|
property kn_id :PtrUint read kn_kevent.ident write kn_kevent.ident ;
|
|
property kn_filter:SmallInt read kn_kevent.filter write kn_kevent.filter;
|
|
property kn_flags :Word read kn_kevent.flags write kn_kevent.flags ;
|
|
property kn_fflags:DWORD read kn_kevent.fflags write kn_kevent.fflags;
|
|
property kn_data :Ptrint read kn_kevent.data write kn_kevent.data ;
|
|
property kn_fp :Pointer read kn_ptr.p_fp write kn_ptr.p_fp ;
|
|
end;
|
|
{$IF sizeof(t_knote)<>128}{$STOP sizeof(t_knote)<>128}{$ENDIF}
|
|
|
|
p_kevent_copyops=^t_kevent_copyops;
|
|
t_kevent_copyops=packed record
|
|
arg :Pointer;
|
|
k_copyout:function(arg:Pointer;kevp:p_kevent;count:Integer):Integer;
|
|
k_copyin :function(arg:Pointer;kevp:p_kevent;count:Integer):Integer;
|
|
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;
|
|
|
|
procedure knote(list:p_knlist;hint:QWORD;lockflags:Integer); external;
|
|
|
|
procedure knlist_add (knl:p_knlist;kn:p_knote;islocked:Integer); external;
|
|
procedure knlist_remove(knl:p_knlist;kn:p_knote;islocked:Integer); external;
|
|
|
|
procedure knote_fdclose(fd:Integer); external;
|
|
|
|
procedure knlist_init(knl:p_knlist;lock,kl_lock,kl_unlock,kl_assert_locked,kl_assert_unlocked:Pointer); external;
|
|
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);
|
|
procedure KNOTE_UNLOCKED(list:p_knlist;hint:QWORD);
|
|
|
|
procedure knlist_clear (knl:p_knlist;islocked:Integer); inline;
|
|
procedure knlist_delete(knl:p_knlist;islocked:Integer); inline;
|
|
|
|
function M_KNLIST_EMPTY(list:p_knlist):Boolean;
|
|
|
|
//
|
|
|
|
procedure EV_SET(kevp:p_kevent;a:PtrUint;b:SmallInt;c:Word;d:DWORD;e:Ptrint;f:Pointer);
|
|
function EVFILT_NAME(i:Integer):RawByteString;
|
|
|
|
implementation
|
|
|
|
procedure KNOTE_LOCKED(list:p_knlist;hint:QWORD);
|
|
begin
|
|
knote(list, hint, KNF_LISTLOCKED);
|
|
end;
|
|
|
|
procedure KNOTE_UNLOCKED(list:p_knlist;hint:QWORD);
|
|
begin
|
|
knote(list, hint, 0);
|
|
end;
|
|
|
|
procedure knlist_clear(knl:p_knlist;islocked:Integer); inline;
|
|
begin
|
|
knlist_cleardel(knl, islocked, 0)
|
|
end;
|
|
|
|
procedure knlist_delete(knl:p_knlist;islocked:Integer); inline;
|
|
begin
|
|
knlist_cleardel(knl, islocked, 1)
|
|
end;
|
|
|
|
function M_KNLIST_EMPTY(list:p_knlist):Boolean;
|
|
begin
|
|
Result:=SLIST_EMPTY(@list^.kl_list);
|
|
end;
|
|
|
|
procedure EV_SET(kevp:p_kevent;a:PtrUint;b:SmallInt;c:Word;d:DWORD;e:Ptrint;f:Pointer);
|
|
begin
|
|
(kevp)^.ident :=(a);
|
|
(kevp)^.filter:=(b);
|
|
(kevp)^.flags :=(c);
|
|
(kevp)^.fflags:=(d);
|
|
(kevp)^.data :=(e);
|
|
(kevp)^.udata :=(f);
|
|
end;
|
|
|
|
function EVFILT_NAME(i:Integer):RawByteString;
|
|
begin
|
|
Result:='';
|
|
case i of
|
|
EVFILT_READ :Result:='EVFILT_READ';
|
|
EVFILT_WRITE :Result:='EVFILT_WRITE';
|
|
EVFILT_AIO :Result:='EVFILT_AIO';
|
|
EVFILT_VNODE :Result:='EVFILT_VNODE';
|
|
EVFILT_PROC :Result:='EVFILT_PROC';
|
|
EVFILT_SIGNAL :Result:='EVFILT_SIGNAL';
|
|
EVFILT_TIMER :Result:='EVFILT_TIMER';
|
|
EVFILT_FS :Result:='EVFILT_FS';
|
|
EVFILT_LIO :Result:='EVFILT_LIO';
|
|
EVFILT_USER :Result:='EVFILT_USER';
|
|
EVFILT_POLLING :Result:='EVFILT_POLLING';
|
|
EVFILT_DISPLAY :Result:='EVFILT_DISPLAY';
|
|
EVFILT_GRAPHICS_CORE :Result:='EVFILT_GRAPHICS_CORE';
|
|
EVFILT_HRTIMER :Result:='EVFILT_HRTIMER';
|
|
EVFILT_UVD_TRAP :Result:='EVFILT_UVD_TRAP';
|
|
EVFILT_VCE_TRAP :Result:='EVFILT_VCE_TRAP';
|
|
EVFILT_SDMA_TRAP :Result:='EVFILT_SDMA_TRAP';
|
|
EVFILT_REG_EV :Result:='EVFILT_REG_EV';
|
|
EVFILT_GPU_EXCEPTION :Result:='EVFILT_GPU_EXCEPTION';
|
|
EVFILT_GPU_SYSTEM_EXCEPTION:Result:='EVFILT_GPU_SYSTEM_EXCEPTION';
|
|
EVFILT_GPU_DBGGC_EV :Result:='EVFILT_GPU_DBGGC_EV';
|
|
EVFILT_CPUMODE :Result:='EVFILT_CPUMODE';
|
|
else
|
|
Str(i,Result);
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|