From 0b8bc3396d302bdf61068b9ccf3abf8cab31fe85 Mon Sep 17 00:00:00 2001 From: red-prig Date: Thu, 9 Mar 2023 21:27:21 +0300 Subject: [PATCH] + --- sys/kern/kern_evf.pas | 223 +++++++++++++++++++++++++++++++++++++++++ sys/kern/kern_osem.pas | 11 +- sys/sys_evf.pas | 67 +++++++++++++ sys/test/project1.lpi | 4 + sys/test/project1.lpr | 3 +- 5 files changed, 302 insertions(+), 6 deletions(-) create mode 100644 sys/sys_evf.pas diff --git a/sys/kern/kern_evf.pas b/sys/kern/kern_evf.pas index 50329e24..502d5dd8 100644 --- a/sys/kern/kern_evf.pas +++ b/sys/kern/kern_evf.pas @@ -10,12 +10,21 @@ const 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; + implementation uses @@ -57,6 +66,9 @@ type waitMode:DWORD; end; +var + evf_table:t_id_desc_table; + function evf_alloc:p_evf; inline; begin Result:=AllocMem(SizeOf(t_evf)); @@ -505,8 +517,219 @@ begin end; +// + +function sys_evf_create(name:PChar;attr:DWORD;initPattern:QWORD):Integer; +var + td:p_kthread; + _name:array[0..31] of Char; + evf:p_evf; + key:Integer; +begin + Result:=EINVAL; + td:=curkthread; + + if ((attr and $fffffecc)<>0) or + ((attr and 3)=3) or + ((attr and $30)=$30) or + (name=nil) then Exit; + + //process shared evf not support + if ((attr and EVF_ATTR_SHRD)<>0) then Exit(EPERM); + + 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; + + FillChar(_name,32,0); + if (copyinstr(name,@_name,32,nil)<>0) then Exit; + + evf:=evf_alloc; + if (evf=nil) then Exit(ENOMEM); //EAGAIN + + evf_init(evf,attr,initPattern); + evf^.name:=_name; + + if not id_new(@evf_table,@evf^.desc,@key) then + begin + evf_free(evf); + Exit(EAGAIN); + end; + id_release(@evf^.desc); + + td^.td_retval[0]:=key; + + Result:=0; +end; + +function sys_evf_delete(key:Integer):Integer; +var + evf:p_evf; +begin + Result:=ESRCH; + + evf:=p_evf(id_get(@evf_table,key)); + if (evf=nil) then Exit; + + evf_delete(evf); + id_release(@evf^.desc); + + if not id_del(@evf_table,key) then Exit; + + Result:=0; +end; + +function sys_evf_cancel(key:Integer;setPattern:QWORD;pNumWait:PInteger):Integer; +var + evf:p_evf; + num:Integer; + r:Integer; +begin + Result:=ESRCH; + num:=0; + + evf:=p_evf(id_get(@evf_table,key)); + if (evf=nil) then Exit; + + Result:=0; + num:=evf_cancel(evf,setPattern); + id_release(@evf^.desc); + + if (pNumWait<>nil) then + begin + r:=copyout(@num,pNumWait,SizeOf(Integer)); + if (r<>0) then Result:=EFAULT; + end; +end; + +function sys_evf_clear(key:Integer;bitPattern:QWORD):Integer; +var + evf:p_evf; +begin + Result:=ESRCH; + + evf:=p_evf(id_get(@evf_table,key)); + if (evf=nil) then Exit; + + evf_clear(evf,bitPattern); + id_release(@evf^.desc); + + Result:=0; +end; + +function sys_evf_set(key:Integer;bitPattern:QWORD):Integer; +var + evf:p_evf; +begin + Result:=ESRCH; + + evf:=p_evf(id_get(@evf_table,key)); + if (evf=nil) then Exit; + + evf_set(evf,bitPattern); + id_release(@evf^.desc); + + Result:=0; +end; + +function sys_evf_trywait(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD):Integer; +var + evf:p_evf; + res:QWORD; + r:Integer; +begin + Result:=EINVAL; + + if ((waitMode and 3)=0) or + ((waitMode and 3)=3) or + ((waitMode and $30)=$30) or + (bitPattern=0) then Exit; + + Result:=ESRCH; + + evf:=p_evf(id_get(@evf_table,key)); + if (evf=nil) then Exit; + + if (pRes=nil) then + begin + Result:=evf_trywait(evf,bitPattern,waitMode,nil); + r:=0; + end else + begin + res:=0; + Result:=evf_trywait(evf,bitPattern,waitMode,@res); + r:=copyout(@res,pRes,SizeOf(QWORD)); + end; + + id_release(@evf^.desc); + + if (r<>0) then Result:=EFAULT; +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; + r:Integer; +begin + Result:=EINVAL; + + if ((waitMode and 3)=0) or + ((waitMode and 3)=3) or + ((waitMode and $30)=$30) or + (bitPattern=0) then Exit; + + time:=0; + timeout:=nil; + + if (pTimeout<>nil) then + begin + Result:=copyin(pTimeout,@time,SizeOf(DWORD)); + if (Result<>0) then Exit; + timeout:=@time; + end; + + Result:=ESRCH; + + evf:=p_evf(id_get(@evf_table,key)); + if (evf=nil) then Exit; + + if (pRes=nil) then + begin + Result:=evf_wait(evf,bitPattern,waitMode,nil,timeout); + r:=0; + end else + begin + res:=0; + Result:=evf_wait(evf,bitPattern,waitMode,@res,timeout); + r:=copyout(@res,pRes,SizeOf(QWORD)); + end; + + id_release(@evf^.desc); + + if (r=0) and (pTimeout<>nil) then + begin + r:=copyout(@time,pTimeout,SizeOf(DWORD)); + end; + + if (r<>0) then Result:=EFAULT; +end; +initialization + id_table_init(@evf_table,1); + +finalization + id_table_fini(@evf_table); end. + diff --git a/sys/kern/kern_osem.pas b/sys/kern/kern_osem.pas index ed0cf94d..5afb1641 100644 --- a/sys/kern/kern_osem.pas +++ b/sys/kern/kern_osem.pas @@ -387,19 +387,20 @@ begin Result:=EINVAL; td:=curkthread; - if ((attr and $fffffefc)<>0) or ((attr and 3)=3) then Exit; - - //process shared osem not support - if ((attr and SEMA_ATTR_SHRD)<>0) then Exit(EPERM); + if ((attr and $fffffefc)<>0) or + ((attr and 3)=3) then Exit; if (initCount<0) or (maxCount<=0) or (initCount>maxCount) or (name=nil) then Exit; + //process shared osem not support + if ((attr and SEMA_ATTR_SHRD)<>0) then Exit(EPERM); + if ((attr and 3)=0) then begin - attr:=attr or 1; + attr:=attr or SEMA_ATTR_FIFO; end; FillChar(_name,32,0); diff --git a/sys/sys_evf.pas b/sys/sys_evf.pas new file mode 100644 index 00000000..3bc9b340 --- /dev/null +++ b/sys/sys_evf.pas @@ -0,0 +1,67 @@ +unit sys_evf; + +{$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} + +interface + +function evf_create(name:PChar;attr:DWORD;initPattern:QWORD):Integer; +function _evf_delete_err(key:Integer):Integer; +function _evf_cancel_err(key:Integer;setPattern:QWORD;pNumWait:PInteger):Integer; +function _evf_clear_err(key:Integer;bitPattern:QWORD):Integer; +function _evf_set_err(key:Integer;bitPattern:QWORD):Integer; +function _evf_trywait_err(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD):Integer; +function _evf_wait_err(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD;pTimeout:PDWORD):Integer; + +implementation + +uses + kern_evf, + trap, + thr_error; + +function evf_create(name:PChar;attr:DWORD;initPattern:QWORD):Integer; assembler; nostackframe; +asm + movq sys_evf_create,%rax + call fast_syscall + call cerror +end; + +function _evf_delete_err(key:Integer):Integer; assembler; nostackframe; +asm + movq sys_evf_delete,%rax + call fast_syscall +end; + +function _evf_cancel_err(key:Integer;setPattern:QWORD;pNumWait:PInteger):Integer; assembler; nostackframe; +asm + movq sys_evf_cancel,%rax + call fast_syscall +end; + +function _evf_clear_err(key:Integer;bitPattern:QWORD):Integer; assembler; nostackframe; +asm + movq sys_evf_clear,%rax + call fast_syscall +end; + +function _evf_set_err(key:Integer;bitPattern:QWORD):Integer; assembler; nostackframe; +asm + movq sys_evf_set,%rax + call fast_syscall +end; + +function _evf_trywait_err(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD):Integer; assembler; nostackframe; +asm + movq sys_evf_trywait,%rax + call fast_syscall +end; + +function _evf_wait_err(key:Integer;bitPattern:QWORD;waitMode:DWORD;pRes:PQWORD;pTimeout:PDWORD):Integer; assembler; nostackframe; +asm + movq sys_evf_wait,%rax + call fast_syscall +end; + +end. + diff --git a/sys/test/project1.lpi b/sys/test/project1.lpi index 9aa5e375..592f67c1 100644 --- a/sys/test/project1.lpi +++ b/sys/test/project1.lpi @@ -197,6 +197,10 @@ + + + + diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr index 23d2717a..7add5e30 100644 --- a/sys/test/project1.lpr +++ b/sys/test/project1.lpr @@ -31,7 +31,8 @@ uses kern_osem, kern_id, sys_osem, - kern_evf; + kern_evf, + sys_evf; var mtx:umutex;