mirror of https://github.com/red-prig/fpPS4.git
769 lines
15 KiB
Plaintext
769 lines
15 KiB
Plaintext
unit kern_evf;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
const
|
|
EVF_ATTR_TH_FIFO =$01;
|
|
EVF_ATTR_TH_PRIO =$02;
|
|
EVF_ATTR_SINGLE =$10;
|
|
EVF_ATTR_MULTI =$20;
|
|
EVF_ATTR_SHRD =$100;
|
|
|
|
EVF_WAITMODE_AND =$01;
|
|
EVF_WAITMODE_OR =$02;
|
|
EVF_WAITMODE_CLEAR_ALL=$10;
|
|
EVF_WAITMODE_CLEAR_PAT=$20;
|
|
|
|
function sys_evf_create(name:PChar;attr:DWORD;initPattern:QWORD):Integer;
|
|
function sys_evf_delete(key:Integer):Integer;
|
|
function sys_evf_cancel(key:Integer;setPattern:QWORD;pNumWait:PInteger):Integer;
|
|
function sys_evf_clear(key:Integer;bitPattern:QWORD):Integer;
|
|
function sys_evf_set(key:Integer;bitPattern:QWORD):Integer;
|
|
function sys_evf_trywait(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD):Integer;
|
|
function sys_evf_wait(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD;pTimeout:PDWORD):Integer;
|
|
function sys_evf_open(name:PChar):Integer;
|
|
function sys_evf_close(key:Integer):Integer;
|
|
|
|
implementation
|
|
|
|
uses
|
|
mqueue,
|
|
errno,
|
|
systm,
|
|
time,
|
|
md_time,
|
|
kern_mtx,
|
|
kern_thr,
|
|
kern_condvar,
|
|
kern_named_id,
|
|
kern_namedobj;
|
|
|
|
const
|
|
EVF_ATTR_DELF =$1000;
|
|
|
|
EVF_WAITMODE_CANCEL=$100;
|
|
EVF_WAITMODE_DELETE=$200;
|
|
|
|
EVF_OBJT =$110;
|
|
|
|
type
|
|
p_evf=^t_evf;
|
|
t_evf=packed object(t_id_named_desc)
|
|
bitPattern:QWORD;
|
|
mtx :mtx;
|
|
cv :t_cv;
|
|
_align :Integer;
|
|
list :TAILQ_HEAD;
|
|
attr :DWORD;
|
|
wait_count:Integer;
|
|
end;
|
|
|
|
p_evf_node=^t_evf_node;
|
|
t_evf_node=packed record
|
|
entry :TAILQ_ENTRY;
|
|
td :p_kthread;
|
|
bpattern:QWORD;
|
|
rpattern:QWORD;
|
|
waitMode:DWORD;
|
|
end;
|
|
|
|
function evf_alloc:p_evf; inline;
|
|
begin
|
|
Result:=AllocMem(SizeOf(t_evf));
|
|
end;
|
|
|
|
procedure evf_free(data:pointer);
|
|
begin
|
|
mtx_destroy(p_evf(data)^.mtx);
|
|
FreeMem(data);
|
|
end;
|
|
|
|
function evf_init(evf:p_evf;attr:DWORD;initPattern:QWORD):Integer;
|
|
begin
|
|
evf^.desc.free:=@evf_free;
|
|
evf^.objt:=EVF_OBJT;
|
|
evf^.bitPattern:=initPattern;
|
|
mtx_init(evf^.mtx,'evf mtx');
|
|
cv_init(@evf^.cv,'evf cv');
|
|
TAILQ_INIT(@evf^.list);
|
|
evf^.wait_count:=0;
|
|
evf^.attr:=attr;
|
|
Result:=0;
|
|
end;
|
|
|
|
procedure evf_delete(evf:p_evf);
|
|
var
|
|
node,next:p_evf_node;
|
|
begin
|
|
mtx_lock(evf^.mtx);
|
|
|
|
if ((evf^.attr and EVF_ATTR_DELF)=0) then
|
|
begin
|
|
evf^.attr:=evf^.attr or EVF_ATTR_DELF;
|
|
node:=TAILQ_FIRST(@evf^.list);
|
|
while (node<>nil) do
|
|
begin
|
|
next:=node^.entry.tqe_next;
|
|
if (next=nil) then
|
|
begin
|
|
evf^.list.tqh_last:=node^.entry.tqe_prev;
|
|
end else
|
|
begin
|
|
next^.entry.tqe_prev:=node^.entry.tqe_prev;
|
|
end;
|
|
node^.entry.tqe_prev^:=node^.entry.tqe_next;
|
|
node^.waitMode:=node^.waitMode or EVF_WAITMODE_DELETE;
|
|
node:=next;
|
|
end;
|
|
cv_broadcastpri(@evf^.cv,0);
|
|
while (evf^.wait_count<>0) do
|
|
begin
|
|
_cv_wait_sig(@evf^.cv,@evf^.mtx);
|
|
end;
|
|
end;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
end;
|
|
|
|
function evf_cancel(evf:p_evf;setPattern:QWORD):Integer;
|
|
var
|
|
node,next:p_evf_node;
|
|
begin
|
|
mtx_lock(evf^.mtx);
|
|
|
|
//Writeln('evf_cancel(',HexStr(evf),',',HexStr(setPattern,16),')');
|
|
|
|
if ((evf^.attr and EVF_ATTR_DELF)=0) then
|
|
begin
|
|
evf^.bitPattern:=setPattern;
|
|
Result:=evf^.wait_count;
|
|
node:=TAILQ_FIRST(@evf^.list);
|
|
while (node<>nil) do
|
|
begin
|
|
next:=node^.entry.tqe_next;
|
|
if (next=nil) then
|
|
begin
|
|
evf^.list.tqh_last:=node^.entry.tqe_prev;
|
|
end else
|
|
begin
|
|
next^.entry.tqe_prev:=node^.entry.tqe_prev;
|
|
end;
|
|
node^.entry.tqe_prev^:=node^.entry.tqe_next;
|
|
node^.waitMode:=node^.waitMode or EVF_WAITMODE_CANCEL;
|
|
node:=next;
|
|
end;
|
|
cv_broadcastpri(@evf^.cv,0);
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
end else
|
|
begin
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Result:=0;
|
|
end;
|
|
end;
|
|
|
|
procedure evf_clear(evf:p_evf;bitPattern:QWORD);
|
|
begin
|
|
mtx_lock(evf^.mtx);
|
|
|
|
evf^.bitPattern:=evf^.bitPattern and bitPattern;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
end;
|
|
|
|
procedure evf_set(evf:p_evf;bitPattern:QWORD);
|
|
label
|
|
_LAST,
|
|
_SIGNAL;
|
|
var
|
|
node,next:p_evf_node;
|
|
prev:Pointer;
|
|
pattern :QWORD;
|
|
npattern :QWORD;
|
|
nwaitMode:DWORD;
|
|
begin
|
|
mtx_lock(evf^.mtx);
|
|
|
|
//Writeln('evf_set(',HexStr(evf),',',HexStr(bitPattern,16),')');
|
|
|
|
if ((evf^.attr and EVF_ATTR_DELF)=0) then
|
|
begin
|
|
pattern:=bitPattern or evf^.bitPattern;
|
|
evf^.bitPattern:=pattern;
|
|
node:=TAILQ_FIRST(@evf^.list);
|
|
repeat
|
|
if (node=nil) then break;
|
|
next:=node^.entry.tqe_next;
|
|
npattern :=node^.bpattern;
|
|
nwaitMode:=node^.waitMode;
|
|
if ((nwaitMode and EVF_WAITMODE_AND)=0) then
|
|
begin
|
|
//PRIO
|
|
if ((npattern and Pattern)<>0) then
|
|
begin
|
|
node^.rpattern:=Pattern;
|
|
if ((nwaitMode and EVF_ATTR_SINGLE)=0) then
|
|
begin
|
|
if ((nwaitMode and EVF_ATTR_MULTI)<>0) then
|
|
begin
|
|
evf^.bitPattern:=(not npattern) and evf^.bitPattern;
|
|
end;
|
|
end else
|
|
begin
|
|
evf^.bitPattern:=0;
|
|
end;
|
|
prev:=node^.entry.tqe_prev;
|
|
if (node^.entry.tqe_next=nil) then
|
|
begin
|
|
_LAST:
|
|
evf^.list.tqh_last:=prev;
|
|
end else
|
|
begin
|
|
p_evf_node(node^.entry.tqe_next)^.entry.tqe_prev:=prev;
|
|
end;
|
|
_SIGNAL:
|
|
node^.entry.tqe_prev^:=node^.entry.tqe_next;
|
|
|
|
cv_signalto(@evf^.cv,node^.td);
|
|
end;
|
|
end else
|
|
if ((npattern and Pattern)=npattern) then
|
|
begin
|
|
//FIFO
|
|
node^.rpattern:=Pattern;
|
|
if ((nwaitMode and EVF_ATTR_SINGLE)=0) then
|
|
begin
|
|
if ((nwaitMode and EVF_ATTR_MULTI)<>0) then
|
|
begin
|
|
evf^.bitPattern:=(not npattern) and evf^.bitPattern;
|
|
end;
|
|
end else
|
|
begin
|
|
evf^.bitPattern:=0;
|
|
end;
|
|
prev:=node^.entry.tqe_prev;
|
|
if (node^.entry.tqe_next=nil) then goto _LAST;
|
|
p_evf_node(node^.entry.tqe_next)^.entry.tqe_prev:=prev;
|
|
goto _SIGNAL;
|
|
end;
|
|
Pattern:=evf^.bitPattern;
|
|
node:=next;
|
|
until (pattern=0);
|
|
end;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
end;
|
|
|
|
function evf_trywait(evf:p_evf;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD):Integer;
|
|
label
|
|
_RESULT;
|
|
var
|
|
pattern:QWORD;
|
|
begin
|
|
mtx_lock(evf^.mtx);
|
|
|
|
//Writeln('evf_trywait(',HexStr(evf),',',HexStr(bitPattern,16),',',waitMode,')');
|
|
|
|
if ((evf^.attr and EVF_ATTR_DELF)=0) then
|
|
begin
|
|
if (((evf^.attr and EVF_ATTR_SINGLE)=0) or (evf^.wait_count=0)) then
|
|
begin
|
|
pattern:=evf^.bitPattern;
|
|
|
|
if ((waitMode and EVF_WAITMODE_AND)=0) then
|
|
begin
|
|
if ((pattern and bitPattern)=0) then goto _RESULT;
|
|
if (pRes<>nil) then
|
|
begin
|
|
pRes^:=pattern;
|
|
end;
|
|
if ((waitMode and EVF_ATTR_SINGLE)=0) then
|
|
begin
|
|
if ((waitMode and EVF_ATTR_MULTI)<>0) then
|
|
begin
|
|
evf^.bitPattern:=(not bitPattern) and evf^.bitPattern;
|
|
end;
|
|
end else
|
|
begin
|
|
evf^.bitPattern:=0;
|
|
end;
|
|
end else
|
|
begin
|
|
if ((pattern and bitPattern)<>bitPattern) then
|
|
begin
|
|
_RESULT:
|
|
if (pRes<>nil) then
|
|
begin
|
|
pRes^:=pattern;
|
|
end;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Exit(EBUSY);
|
|
end;
|
|
if (pRes<>nil) then
|
|
begin
|
|
pRes^:=pattern;
|
|
end;
|
|
if ((waitMode and EVF_ATTR_SINGLE)=0) then
|
|
begin
|
|
if ((waitMode and EVF_ATTR_MULTI)<>0) then
|
|
begin
|
|
evf^.bitPattern:=(not bitPattern) and evf^.bitPattern;
|
|
end;
|
|
end else
|
|
begin
|
|
evf^.bitPattern:=0;
|
|
end;
|
|
end;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Exit(0);
|
|
end;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Result:=EPERM;
|
|
end else
|
|
begin
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Result:=EACCES;
|
|
end;
|
|
end;
|
|
|
|
function evf_wait(evf:p_evf;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD;timeout:PDWORD):Integer;
|
|
label
|
|
_WAIT,
|
|
_FIFO,
|
|
_SIGNAL;
|
|
var
|
|
td:p_kthread;
|
|
node:t_evf_node;
|
|
node2,node3:p_evf_node;
|
|
ts:timespec;
|
|
t1,t2,t3:Int64;
|
|
pattern:QWORD;
|
|
attr:DWORD;
|
|
_pri:Integer;
|
|
count:Integer;
|
|
begin
|
|
td:=curkthread;
|
|
|
|
//Writeln('evf_wait(',HexStr(evf),',',HexStr(bitPattern,16),',',waitMode,')');
|
|
|
|
mtx_lock(evf^.mtx);
|
|
|
|
attr:=evf^.attr;
|
|
if ((attr and EVF_ATTR_DELF)=0) then
|
|
begin
|
|
if (((attr and EVF_ATTR_SINGLE)<>0) and (evf^.wait_count<>0)) then
|
|
begin
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Exit(EPERM);
|
|
end;
|
|
pattern:=evf^.bitPattern;
|
|
if ((waitMode and EVF_WAITMODE_AND)=0) then
|
|
begin
|
|
if ((pattern and bitPattern)=0) then goto _WAIT;
|
|
if (pRes<>nil) then
|
|
begin
|
|
pRes^:=pattern;
|
|
end;
|
|
if ((waitMode and EVF_ATTR_SINGLE)=0) then
|
|
begin
|
|
if ((waitMode and EVF_ATTR_MULTI)<>0) then
|
|
begin
|
|
evf^.bitPattern:=(not bitPattern) and evf^.bitPattern;
|
|
end;
|
|
end else
|
|
begin
|
|
evf^.bitPattern:=0;
|
|
end;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Exit(0);
|
|
end else
|
|
begin
|
|
if ((pattern and bitPattern)<>bitPattern) then
|
|
begin
|
|
_WAIT:
|
|
|
|
node:=Default(t_evf_node);
|
|
node.td:=td;
|
|
node.bpattern:=bitPattern;
|
|
node.waitMode:=waitMode;
|
|
|
|
if ((attr and EVF_ATTR_TH_FIFO)=0) then
|
|
begin
|
|
//PRIO
|
|
node.entry.tqe_next:=@evf^.list.tqh_first;
|
|
repeat
|
|
node.entry.tqe_next:=p_evf_node(node.entry.tqe_next)^.entry.tqe_next;
|
|
if (node.entry.tqe_next=nil) then goto _FIFO;
|
|
_pri:=p_evf_node(node.entry.tqe_next)^.td^.td_base_pri;
|
|
until not ((_pri<td^.td_base_pri) or (_pri=td^.td_base_pri));
|
|
|
|
// INSERT BETWEN
|
|
node.entry.tqe_prev:=p_evf_node(node.entry.tqe_next)^.entry.tqe_prev;
|
|
p_evf_node(node.entry.tqe_next)^.entry.tqe_prev^:=@node;
|
|
p_evf_node(node.entry.tqe_next)^.entry.tqe_prev:=@node.entry.tqe_next;
|
|
end else
|
|
begin
|
|
_FIFO:
|
|
// INSERT LAST
|
|
node.entry.tqe_next:=nil;
|
|
node.entry.tqe_prev:=evf^.list.tqh_last;
|
|
node.entry.tqe_prev^:=@node;
|
|
evf^.list.tqh_last:=@node.entry.tqe_next;
|
|
end;
|
|
evf^.wait_count:=evf^.wait_count+1;
|
|
|
|
if (timeout=nil) then
|
|
begin
|
|
Result:=_cv_wait_sig(@evf^.cv,@evf^.mtx);
|
|
end else
|
|
begin
|
|
usec2timespec(@ts,timeout^);
|
|
t1:=get_unit_uptime;
|
|
Result:=_cv_timedwait_sig_proctime(@evf^.cv,@evf^.mtx,@ts);
|
|
t2:=get_unit_uptime;
|
|
t3:=cputick2usec(t2-t1);
|
|
if (t3<timeout^) then
|
|
begin
|
|
timeout^:=timeout^-DWORD(t3);
|
|
end else
|
|
begin
|
|
timeout^:=0;
|
|
end;
|
|
end;
|
|
if (Result<>0) then
|
|
begin
|
|
node2:=evf^.list.tqh_first;
|
|
repeat
|
|
node3:=node2;
|
|
if (node3=nil) then
|
|
begin
|
|
Result:=0;
|
|
goto _SIGNAL;
|
|
end;
|
|
node2:=node3^.entry.tqe_next;
|
|
until (node3=@node);
|
|
if (node2=nil) then
|
|
begin
|
|
evf^.list.tqh_last:=node.entry.tqe_prev;
|
|
end else
|
|
begin
|
|
node2^.entry.tqe_prev:=node.entry.tqe_prev;
|
|
end;
|
|
node.entry.tqe_prev^:=node3^.entry.tqe_next;
|
|
if (Result=EWOULDBLOCK) then
|
|
begin
|
|
timeout^:=0;
|
|
Result:=ETIMEDOUT;
|
|
end;
|
|
node.rpattern:=evf^.bitPattern;
|
|
end;
|
|
_SIGNAL:
|
|
|
|
count:=evf^.wait_count-1;
|
|
evf^.wait_count:=count;
|
|
|
|
if ((evf^.attr and EVF_ATTR_DELF)<>0) and (count=0) then
|
|
begin
|
|
cv_signal(@evf^.cv);
|
|
end;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
if (pRes<>nil) then
|
|
begin
|
|
pRes^:=node.rpattern;
|
|
end;
|
|
|
|
if ((node.waitMode and EVF_WAITMODE_CANCEL)=0) then
|
|
begin
|
|
if ((node.waitMode and EVF_WAITMODE_DELETE)<>0) then
|
|
begin
|
|
Result:=EACCES;
|
|
end;
|
|
end else
|
|
begin
|
|
Result:=ECANCELED;
|
|
end;
|
|
|
|
Exit;
|
|
end;
|
|
if (pRes<>nil) then
|
|
begin
|
|
pRes^:=pattern;
|
|
end;
|
|
if ((waitMode and EVF_ATTR_SINGLE)=0) then
|
|
begin
|
|
if ((waitMode and EVF_ATTR_MULTI)<>0) then
|
|
begin
|
|
evf^.bitPattern:=(not bitPattern) and evf^.bitPattern;
|
|
end;
|
|
end else
|
|
begin
|
|
evf^.bitPattern:=0;
|
|
end;
|
|
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Exit(0);
|
|
end;
|
|
end else
|
|
begin
|
|
mtx_unlock(evf^.mtx);
|
|
|
|
Exit(EACCES);
|
|
end;
|
|
end;
|
|
|
|
//
|
|
|
|
function sys_evf_create(name:PChar;attr:DWORD;initPattern:QWORD):Integer;
|
|
var
|
|
td:p_kthread;
|
|
_name:t_id_name;
|
|
evf:p_evf;
|
|
key:Integer;
|
|
begin
|
|
Result:=EINVAL;
|
|
|
|
td:=curkthread;
|
|
if (td=nil) then Exit(-1);
|
|
|
|
if ((attr and $fffffecc)<>0) or
|
|
((attr and 3)=3) or
|
|
((attr and $30)=$30) or
|
|
(name=nil) then Exit;
|
|
|
|
if ((attr and EVF_ATTR_SHRD)<>0) then
|
|
begin
|
|
Writeln(StdErr,'sys_evf_create:',name,':process shared evf not supported');
|
|
//Exit(EPERM);
|
|
end;
|
|
|
|
if ((attr and 3)=0) then
|
|
begin
|
|
attr:=attr or EVF_ATTR_TH_FIFO;
|
|
end;
|
|
|
|
if ((attr and $30)=0) then
|
|
begin
|
|
attr:=attr or EVF_ATTR_SINGLE;
|
|
end;
|
|
|
|
_name:=Default(t_id_name);
|
|
Result:=copyinstr(name,@_name,32,nil);
|
|
if (Result<>0) then Exit;
|
|
|
|
evf:=evf_alloc;
|
|
if (evf=nil) then Exit(ENOMEM); //EAGAIN
|
|
|
|
evf_init(evf,attr,initPattern);
|
|
evf^.name:=_name;
|
|
|
|
//Writeln('evf_create(',HexStr(evf),',',name,',',HexStr(attr,2),',',HexStr(initPattern,16),')');
|
|
|
|
if not id_name_new(@named_table,evf,@key) then
|
|
begin
|
|
evf_free(evf);
|
|
Exit(EAGAIN);
|
|
end;
|
|
id_release(evf);
|
|
|
|
td^.td_retval[0]:=key;
|
|
|
|
Result:=0;
|
|
end;
|
|
|
|
function sys_evf_delete(key:Integer):Integer;
|
|
var
|
|
evf:p_evf;
|
|
begin
|
|
Result:=ESRCH;
|
|
|
|
if not id_name_del(@named_table,key,EVF_OBJT,@evf) then Exit;
|
|
|
|
evf_delete(evf);
|
|
id_release(evf);
|
|
|
|
Result:=0;
|
|
end;
|
|
|
|
function sys_evf_cancel(key:Integer;setPattern:QWORD;pNumWait:PInteger):Integer;
|
|
var
|
|
evf:p_evf;
|
|
num:Integer;
|
|
begin
|
|
Result:=ESRCH;
|
|
num:=0;
|
|
|
|
evf:=id_name_get(@named_table,key,EVF_OBJT);
|
|
if (evf=nil) then Exit;
|
|
|
|
Result:=0;
|
|
num:=evf_cancel(evf,setPattern);
|
|
id_release(evf); //<-id_name_new
|
|
|
|
if (pNumWait=nil) then
|
|
begin
|
|
Result:=0;
|
|
end else
|
|
begin
|
|
Result:=copyout(@num,pNumWait,SizeOf(Integer));
|
|
end;
|
|
end;
|
|
|
|
function sys_evf_clear(key:Integer;bitPattern:QWORD):Integer;
|
|
var
|
|
evf:p_evf;
|
|
begin
|
|
Result:=ESRCH;
|
|
|
|
evf:=id_name_get(@named_table,key,EVF_OBJT);
|
|
if (evf=nil) then Exit;
|
|
|
|
evf_clear(evf,bitPattern);
|
|
id_release(evf); //<-id_name_new
|
|
|
|
Result:=0;
|
|
end;
|
|
|
|
function sys_evf_set(key:Integer;bitPattern:QWORD):Integer;
|
|
var
|
|
evf:p_evf;
|
|
begin
|
|
Result:=ESRCH;
|
|
|
|
evf:=id_name_get(@named_table,key,EVF_OBJT);
|
|
if (evf=nil) then Exit;
|
|
|
|
evf_set(evf,bitPattern);
|
|
id_release(evf); //<-id_name_new
|
|
|
|
Result:=0;
|
|
end;
|
|
|
|
function sys_evf_trywait(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD):Integer;
|
|
var
|
|
evf:p_evf;
|
|
res:QWORD;
|
|
ret_c,ret_w:Integer;
|
|
begin
|
|
|
|
if ((waitMode and 3)=0) or
|
|
((waitMode and 3)=3) or
|
|
((waitMode and $30)=$30) or
|
|
(bitPattern=0) then
|
|
begin
|
|
Exit(EINVAL);
|
|
end;
|
|
|
|
evf:=id_name_get(@named_table,key,EVF_OBJT);
|
|
if (evf=nil) then Exit(ESRCH);
|
|
|
|
if (pRes=nil) then
|
|
begin
|
|
ret_w:=evf_trywait(evf,bitPattern,waitMode,nil);
|
|
ret_c:=0;
|
|
end else
|
|
begin
|
|
res:=0;
|
|
ret_w:=evf_trywait(evf,bitPattern,waitMode,@res);
|
|
ret_c:=copyout(@res,pRes,SizeOf(QWORD));
|
|
end;
|
|
|
|
id_release(evf); //<-id_name_new
|
|
|
|
if (ret_w<>0) then ret_c:=ret_w;
|
|
Result:=ret_c;
|
|
end;
|
|
|
|
function sys_evf_wait(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD;pTimeout:PDWORD):Integer;
|
|
var
|
|
evf:p_evf;
|
|
res:QWORD;
|
|
timeout:PDWORD;
|
|
time:DWORD;
|
|
ret_c,ret_w:Integer;
|
|
begin
|
|
|
|
if ((waitMode and 3)=0) or
|
|
((waitMode and 3)=3) or
|
|
((waitMode and $30)=$30) or
|
|
(bitPattern=0) then
|
|
begin
|
|
Exit(EINVAL);
|
|
end;
|
|
|
|
time:=0;
|
|
timeout:=nil;
|
|
|
|
if (pTimeout<>nil) then
|
|
begin
|
|
ret_c:=copyin(pTimeout,@time,SizeOf(DWORD));
|
|
if (ret_c<>0) then Exit(ret_c);
|
|
timeout:=@time;
|
|
end;
|
|
|
|
evf:=id_name_get(@named_table,key,EVF_OBJT);
|
|
if (evf=nil) then Exit(ESRCH);
|
|
|
|
if (pRes=nil) then
|
|
begin
|
|
ret_w:=evf_wait(evf,bitPattern,waitMode,nil,timeout);
|
|
ret_c:=0;
|
|
end else
|
|
begin
|
|
res:=0;
|
|
ret_w:=evf_wait(evf,bitPattern,waitMode,@res,timeout);
|
|
ret_c:=copyout(@res,pRes,SizeOf(QWORD));
|
|
end;
|
|
|
|
id_release(evf); //<-id_name_new
|
|
|
|
if (ret_c=0) and (pTimeout<>nil) then
|
|
begin
|
|
ret_c:=copyout(@time,pTimeout,SizeOf(DWORD));
|
|
end;
|
|
|
|
if (ret_w<>0) then ret_c:=ret_w;
|
|
Result:=ret_c;
|
|
end;
|
|
|
|
function sys_evf_open(name:PChar):Integer;
|
|
var
|
|
td:p_kthread;
|
|
begin
|
|
td:=curkthread;
|
|
if (td=nil) then Exit(-1);
|
|
|
|
Writeln(StdErr,'sys_evf_open:',name,':process shared evf not supported');
|
|
//Exit(EPERM);
|
|
|
|
td^.td_retval[0]:=333;
|
|
Result:=0;
|
|
end;
|
|
|
|
function sys_evf_close(key:Integer):Integer;
|
|
begin
|
|
Writeln(StdErr,'sys_evf_close:','process shared evf not supported');
|
|
Exit(EPERM);
|
|
end;
|
|
|
|
|
|
end.
|
|
|
|
|