FPPS4/sys/sys_event.pas

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.