mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
24e6c9a6e8
commit
f258b7e8c5
|
@ -0,0 +1,215 @@
|
|||
unit kern_id;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
hamt,
|
||||
kern_rwlock;
|
||||
|
||||
Const
|
||||
def_max_key=$7FFFFFFF;
|
||||
|
||||
type
|
||||
p_id_desc=^t_id_desc;
|
||||
t_id_desc=packed record
|
||||
refs:QWORD;
|
||||
free:procedure(data:pointer);
|
||||
end;
|
||||
|
||||
p_id_desc_table=^t_id_desc_table;
|
||||
t_id_desc_table=packed record
|
||||
FLock :Pointer;
|
||||
FHAMT :TSTUB_HAMT32;
|
||||
FCount :Integer;
|
||||
FPos :Integer;
|
||||
min_key:Integer;
|
||||
max_key:Integer;
|
||||
end;
|
||||
|
||||
Procedure id_acqure (d:p_id_desc);
|
||||
Procedure id_release(d:p_id_desc);
|
||||
|
||||
procedure id_table_init(t:p_id_desc_table;min:Integer);
|
||||
procedure id_table_fini(t:p_id_desc_table);
|
||||
|
||||
function id_new(t:p_id_desc_table;d:p_id_desc;pKey:PInteger):Boolean;
|
||||
function id_set(t:p_id_desc_table;d:p_id_desc;Key:Integer):Boolean;
|
||||
function id_get(t:p_id_desc_table;Key:Integer):p_id_desc;
|
||||
function id_del(t:p_id_desc_table;Key:Integer):Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
Procedure id_acqure(d:p_id_desc);
|
||||
begin
|
||||
System.InterlockedIncrement64(d^.refs);
|
||||
end;
|
||||
|
||||
Procedure id_release(d:p_id_desc);
|
||||
begin
|
||||
if (System.InterlockedDecrement64(d^.refs)=0) then
|
||||
if (d^.free<>nil) then
|
||||
begin
|
||||
d^.free(d);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _free_data_cb(data,userdata:Pointer); register;
|
||||
begin
|
||||
if (data<>nil) then
|
||||
begin
|
||||
id_release(data);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure id_table_init(t:p_id_desc_table;min:Integer);
|
||||
begin
|
||||
if (t=nil) then Exit;
|
||||
FillChar(t^,SizeOf(t_id_desc_table),0);
|
||||
t^.min_key:=min;
|
||||
t^.max_key:=def_max_key;
|
||||
t^.FPos :=min;
|
||||
end;
|
||||
|
||||
procedure id_table_fini(t:p_id_desc_table);
|
||||
begin
|
||||
if (t=nil) then Exit;
|
||||
HAMT_clear32(@t^.FHAMT,@_free_data_cb,nil);
|
||||
end;
|
||||
|
||||
function id_new(t:p_id_desc_table;d:p_id_desc;pKey:PInteger):Boolean;
|
||||
Label
|
||||
_data,_exit;
|
||||
Var
|
||||
i,m:Integer;
|
||||
data:PPointer;
|
||||
begin
|
||||
Result:=False;
|
||||
if (t=nil) or (d=nil) or (pKey=nil) then Exit;
|
||||
|
||||
rw_wlock(t^.FLock);
|
||||
|
||||
m:=(t^.max_key-t^.min_key);
|
||||
if (t^.FCount>=m+1) then goto _exit;
|
||||
|
||||
if (t^.FPos<t^.min_key) or
|
||||
(t^.FPos>t^.max_key) then
|
||||
begin
|
||||
t^.FPos:=t^.min_key;
|
||||
end;
|
||||
|
||||
if (t^.FCount=0) then
|
||||
begin
|
||||
pKey^:=t^.FPos;
|
||||
Inc(t^.FPos);
|
||||
|
||||
data:=HAMT_insert32(@t^.FHAMT,pKey^,Pointer(d));
|
||||
|
||||
if (data=nil) then goto _exit;
|
||||
if (data^<>Pointer(d)) then goto _exit;
|
||||
end else
|
||||
begin
|
||||
For i:=0 to m do
|
||||
begin
|
||||
pKey^:=t^.FPos;
|
||||
Inc(t^.FPos);
|
||||
|
||||
if (t^.FPos>t^.max_key) then
|
||||
begin
|
||||
t^.FPos:=t^.min_key;
|
||||
end;
|
||||
|
||||
data:=HAMT_insert32(@t^.FHAMT,pKey^,Pointer(d));
|
||||
|
||||
if (data=nil) then goto _exit;
|
||||
if (data^=Pointer(d)) then goto _data;
|
||||
end;
|
||||
goto _exit;
|
||||
end;
|
||||
|
||||
_data:
|
||||
Inc(t^.FCount);
|
||||
id_acqure(d);
|
||||
id_acqure(d);
|
||||
|
||||
Result:=True;
|
||||
|
||||
_exit:
|
||||
rw_wunlock(t^.FLock);
|
||||
end;
|
||||
|
||||
function id_set(t:p_id_desc_table;d:p_id_desc;Key:Integer):Boolean;
|
||||
Label
|
||||
_exit;
|
||||
Var
|
||||
data:PPointer;
|
||||
begin
|
||||
Result:=False;
|
||||
if (t=nil) or (d=nil) or (Key<t^.min_key) or (Key>t^.max_key) then Exit;
|
||||
|
||||
rw_wlock(t^.FLock);
|
||||
|
||||
data:=HAMT_insert32(@t^.FHAMT,Key,Pointer(d));
|
||||
|
||||
if (data=nil) then goto _exit;
|
||||
if (data^<>Pointer(d)) then goto _exit;
|
||||
|
||||
Inc(t^.FCount);
|
||||
id_acqure(d);
|
||||
id_acqure(d);
|
||||
|
||||
Result:=True;
|
||||
|
||||
_exit:
|
||||
rw_wunlock(t^.FLock);
|
||||
end;
|
||||
|
||||
function id_get(t:p_id_desc_table;Key:Integer):p_id_desc;
|
||||
Var
|
||||
data:PPointer;
|
||||
Label
|
||||
_exit;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (t=nil) or (Key<t^.min_key) or (Key>t^.max_key) then Exit;
|
||||
|
||||
rw_rlock(t^.FLock);
|
||||
|
||||
data:=HAMT_search32(@t^.FHAMT,Key);
|
||||
if (data=nil) then Goto _exit;
|
||||
|
||||
Pointer(Result):=data^;
|
||||
if (Result<>nil) then
|
||||
begin
|
||||
id_acqure(Result);
|
||||
end;
|
||||
|
||||
_exit:
|
||||
rw_runlock(t^.FLock);
|
||||
end;
|
||||
|
||||
function id_del(t:p_id_desc_table;Key:Integer):Boolean;
|
||||
Var
|
||||
d:p_id_desc;
|
||||
begin
|
||||
Result:=False;
|
||||
if (t=nil) or (Key<t^.min_key) or (Key>t^.max_key) then Exit;
|
||||
|
||||
rw_wlock(t^.FLock);
|
||||
|
||||
Pointer(d):=HAMT_delete32(@t^.FHAMT,Key);
|
||||
|
||||
if (d<>nil) then
|
||||
begin
|
||||
id_release(d);
|
||||
Dec(t^.FCount);
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
rw_wunlock(t^.FLock);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -5,20 +5,36 @@ unit kern_osem;
|
|||
|
||||
interface
|
||||
|
||||
uses
|
||||
mqueue,
|
||||
kern_mtx,
|
||||
kern_thr,
|
||||
kern_condvar;
|
||||
|
||||
const
|
||||
SEMA_ATTR_FIFO=$1;
|
||||
SEMA_ATTR_PRIO=$2;
|
||||
SEMA_ATTR_DELF=$1000;
|
||||
SEMA_ATTR_SHRD=$1000;
|
||||
|
||||
function sys_osem_create(name:PChar;attr:DWORD;initCount,maxCount:Integer):Integer;
|
||||
function sys_osem_delete(key:Integer):Integer;
|
||||
function sys_osem_cancel(key,setCount:Integer;pNumWait:PInteger):Integer;
|
||||
function sys_osem_post(key,signalCount:Integer):Integer;
|
||||
function sys_osem_trywait(key,needCount:Integer):Integer;
|
||||
function sys_osem_wait(key,needCount:Integer;pTimeout:PDWORD):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
mqueue,
|
||||
errno,
|
||||
systm,
|
||||
time,
|
||||
kern_time,
|
||||
kern_mtx,
|
||||
kern_thr,
|
||||
kern_condvar,
|
||||
kern_id;
|
||||
|
||||
type
|
||||
p_osem=^t_osem;
|
||||
t_osem=packed record
|
||||
desc :t_id_desc;
|
||||
mtx :mtx;
|
||||
cv :t_cv;
|
||||
list :TAILQ_HEAD;
|
||||
|
@ -27,6 +43,7 @@ type
|
|||
init_count:Integer;
|
||||
max_count :Integer;
|
||||
wait_count:Integer;
|
||||
name :array[0..31] of Char;
|
||||
end;
|
||||
|
||||
p_osem_node=^t_osem_node;
|
||||
|
@ -37,15 +54,22 @@ type
|
|||
retval:Integer;
|
||||
end;
|
||||
|
||||
implementation
|
||||
var
|
||||
osem_table:t_id_desc_table;
|
||||
|
||||
uses
|
||||
errno,
|
||||
time,
|
||||
kern_time;
|
||||
function osem_alloc:p_osem; inline;
|
||||
begin
|
||||
Result:=AllocMem(SizeOf(t_osem));
|
||||
end;
|
||||
|
||||
procedure osem_free(data:pointer);
|
||||
begin
|
||||
FreeMem(data);
|
||||
end;
|
||||
|
||||
function osem_init(sem:p_osem;attr:DWORD;initCount,max_count:Integer):Integer;
|
||||
begin
|
||||
sem^.desc.free :=@osem_free;
|
||||
sem^.count :=initCount;
|
||||
sem^.init_count:=initCount;
|
||||
sem^.max_count :=max_count;
|
||||
|
@ -237,7 +261,9 @@ begin
|
|||
begin
|
||||
if (needCount<=sem^.max_count) then
|
||||
begin
|
||||
node.retval:=0;
|
||||
node:=Default(t_osem_node);
|
||||
node.td :=td;
|
||||
node.count:=needCount;
|
||||
if ((sem^.attr and SEMA_ATTR_FIFO)=0) then
|
||||
begin
|
||||
//_PRIO
|
||||
|
@ -262,8 +288,6 @@ begin
|
|||
sem^.list.tqh_last:=@node.entry.tqe_next;
|
||||
end;
|
||||
sem^.wait_count:=sem^.wait_count+1;
|
||||
node.td:=td;
|
||||
node.count:=needCount;
|
||||
if (timeout=nil) then
|
||||
begin
|
||||
Result:=_cv_wait_sig(@sem^.cv,@sem^.mtx);
|
||||
|
@ -348,7 +372,164 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
function sys_osem_create(name:PChar;attr:DWORD;initCount,maxCount:Integer):Integer;
|
||||
var
|
||||
td:p_kthread;
|
||||
_name:array[0..31] of Char;
|
||||
sem:p_osem;
|
||||
key:Integer;
|
||||
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 (initCount<0) or
|
||||
(maxCount<=0) or
|
||||
(initCount>maxCount) or
|
||||
(name=nil) then Exit;
|
||||
|
||||
if ((attr and 3)=0) then
|
||||
begin
|
||||
attr:=attr or 1;
|
||||
end;
|
||||
|
||||
FillChar(_name,32,0);
|
||||
if (copyinstr(name,@_name,32,nil)<>0) then Exit;
|
||||
|
||||
sem:=osem_alloc;
|
||||
if (sem=nil) then Exit(ENOMEM); //EAGAIN
|
||||
|
||||
osem_init(sem,attr,initCount,maxCount);
|
||||
sem^.name:=_name;
|
||||
|
||||
if not id_new(@osem_table,@sem^.desc,@key) then
|
||||
begin
|
||||
osem_free(sem);
|
||||
Exit(EAGAIN);
|
||||
end;
|
||||
id_release(@sem^.desc);
|
||||
|
||||
td^.td_retval[0]:=key;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function sys_osem_delete(key:Integer):Integer;
|
||||
var
|
||||
sem:p_osem;
|
||||
begin
|
||||
Result:=ESRCH;
|
||||
|
||||
sem:=p_osem(id_get(@osem_table,key));
|
||||
if (sem=nil) then Exit;
|
||||
|
||||
osem_delete(sem);
|
||||
id_release(@sem^.desc);
|
||||
|
||||
if not id_del(@osem_table,key) then Exit;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function sys_osem_cancel(key,setCount:Integer;pNumWait:PInteger):Integer;
|
||||
var
|
||||
sem:p_osem;
|
||||
num:Integer;
|
||||
begin
|
||||
Result:=ESRCH;
|
||||
num:=0;
|
||||
|
||||
sem:=p_osem(id_get(@osem_table,key));
|
||||
if (sem=nil) then Exit;
|
||||
|
||||
Result:=osem_cancel(sem,setCount,@num);
|
||||
id_release(@sem^.desc);
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
if (pNumWait<>nil) then
|
||||
begin
|
||||
Result:=copyout(@num,pNumWait,SizeOf(Integer));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function sys_osem_post(key,signalCount:Integer):Integer;
|
||||
var
|
||||
sem:p_osem;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (signalCount<=0) then Exit;
|
||||
|
||||
Result:=ESRCH;
|
||||
|
||||
sem:=p_osem(id_get(@osem_table,key));
|
||||
if (sem=nil) then Exit;
|
||||
|
||||
Result:=osem_post(sem,signalCount);
|
||||
id_release(@sem^.desc);
|
||||
end;
|
||||
|
||||
function sys_osem_trywait(key,needCount:Integer):Integer;
|
||||
var
|
||||
sem:p_osem;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (needCount<=0) then Exit;
|
||||
|
||||
Result:=ESRCH;
|
||||
|
||||
sem:=p_osem(id_get(@osem_table,key));
|
||||
if (sem=nil) then Exit;
|
||||
|
||||
Result:=osem_trywait(sem,needCount);
|
||||
id_release(@sem^.desc);
|
||||
end;
|
||||
|
||||
function sys_osem_wait(key,needCount:Integer;pTimeout:PDWORD):Integer;
|
||||
var
|
||||
sem:p_osem;
|
||||
timeout:PDWORD;
|
||||
time:DWORD;
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
if (needCount<=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;
|
||||
|
||||
sem:=p_osem(id_get(@osem_table,key));
|
||||
if (sem=nil) then Exit;
|
||||
|
||||
Result:=osem_wait(sem,needCount,timeout);
|
||||
id_release(@sem^.desc);
|
||||
|
||||
if (pTimeout<>nil) then
|
||||
begin
|
||||
Result:=copyout(@time,pTimeout,SizeOf(DWORD));
|
||||
end;
|
||||
end;
|
||||
|
||||
initialization
|
||||
id_table_init(@osem_table,1);
|
||||
|
||||
finalization
|
||||
id_table_fini(@osem_table);
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ const
|
|||
_ufssel =(2 shl 3) or 3;
|
||||
_ugssel =(3 shl 3) or 3;
|
||||
|
||||
procedure cpu_set_syscall_retval(td:p_kthread;error:Integer);
|
||||
procedure sendsig(catcher:sig_t;ksi:p_ksiginfo;mask:p_sigset_t);
|
||||
function sys_sigreturn(sigcntxp:p_ucontext_t):Integer;
|
||||
|
||||
|
@ -29,6 +30,33 @@ uses
|
|||
kern_sig,
|
||||
trap;
|
||||
|
||||
procedure cpu_set_syscall_retval(td:p_kthread;error:Integer);
|
||||
begin
|
||||
Case error of
|
||||
0:With td^.td_frame^ do
|
||||
begin
|
||||
tf_rax:=td^.td_retval[0];
|
||||
tf_rdx:=td^.td_retval[1];
|
||||
tf_rflags:=tf_rflags and (not PSL_C);
|
||||
end;
|
||||
ERESTART:
|
||||
With td^.td_frame^ do
|
||||
begin
|
||||
//tf_err = size of syscall cmd
|
||||
tf_rip:=tf_rip-td^.td_frame^.tf_err;
|
||||
tf_r10:=tf_rcx;
|
||||
set_pcb_flags(td,PCB_FULL_IRET);
|
||||
end;
|
||||
EJUSTRETURN:; //nothing
|
||||
else
|
||||
With td^.td_frame^ do
|
||||
begin
|
||||
tf_rax:=error;
|
||||
tf_rflags:=tf_rflags or PSL_C;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function get_fpcontext(td:p_kthread;mcp:p_mcontext_t;xstate:Pointer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
|
|
@ -233,6 +233,10 @@ begin
|
|||
td:=curkthread;
|
||||
td_frame:=td^.td_frame;
|
||||
|
||||
//cpu_fetch_syscall_args
|
||||
td^.td_retval[0]:=0;
|
||||
td^.td_retval[1]:=td_frame^.tf_rdx;
|
||||
|
||||
error:=0;
|
||||
if (td_frame^.tf_rax<>0) then
|
||||
begin
|
||||
|
|
|
@ -18,7 +18,6 @@ var
|
|||
|
||||
function cpu_thread_alloc(td:p_kthread):Integer;
|
||||
function cpu_thread_free(td:p_kthread):Integer;
|
||||
procedure cpu_set_syscall_retval(td:p_kthread;error:Integer);
|
||||
function cpuset_setaffinity(td:p_kthread;new:Ptruint):Integer;
|
||||
function cpuset_setproc(new:Ptruint):Integer;
|
||||
function cpuset_getproc(var old:Ptruint):Integer;
|
||||
|
@ -172,33 +171,6 @@ begin
|
|||
);
|
||||
end;
|
||||
|
||||
procedure cpu_set_syscall_retval(td:p_kthread;error:Integer);
|
||||
begin
|
||||
Case error of
|
||||
0:With td^.td_frame^ do
|
||||
begin
|
||||
tf_rax:=td^.td_retval[0];
|
||||
tf_rdx:=td^.td_retval[1];
|
||||
tf_rflags:=tf_rflags and (not PSL_C);
|
||||
end;
|
||||
ERESTART:
|
||||
With td^.td_frame^ do
|
||||
begin
|
||||
//tf_err = size of syscall cmd
|
||||
tf_rip:=tf_rip-td^.td_frame^.tf_err;
|
||||
tf_r10:=tf_rcx;
|
||||
set_pcb_flags(td,PCB_FULL_IRET);
|
||||
end;
|
||||
EJUSTRETURN:; //nothing
|
||||
else
|
||||
With td^.td_frame^ do
|
||||
begin
|
||||
tf_rax:=error;
|
||||
tf_rflags:=tf_rflags or PSL_C;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function cpuset_setaffinity(td:p_kthread;new:Ptruint):Integer;
|
||||
begin
|
||||
td^.td_cpuset:=new;
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
unit sys_osem;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
function _osem_create_err(name:PChar;attr:DWORD;initCount,maxCount:Integer):Integer;
|
||||
function _osem_delete_err(key:Integer):Integer;
|
||||
function _osem_cancel_err(key,setCount:Integer;pNumWait:PInteger):Integer;
|
||||
function _osem_post_err(key,signalCount:Integer):Integer;
|
||||
function _osem_trywait_err(key,needCount:Integer):Integer;
|
||||
function _osem_wait_err(key,needCount:Integer;pTimeout:PDWORD):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
kern_osem,
|
||||
trap,
|
||||
thr_error;
|
||||
|
||||
function _osem_create_err(name:PChar;attr:DWORD;initCount,maxCount:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq sys_osem_create,%rax
|
||||
call fast_syscall
|
||||
end;
|
||||
|
||||
function _osem_delete_err(key:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq sys_osem_delete,%rax
|
||||
call fast_syscall
|
||||
end;
|
||||
|
||||
function _osem_cancel_err(key,setCount:Integer;pNumWait:PInteger):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq sys_osem_cancel,%rax
|
||||
call fast_syscall
|
||||
end;
|
||||
|
||||
function _osem_post_err(key,signalCount:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq sys_osem_post,%rax
|
||||
call fast_syscall
|
||||
end;
|
||||
|
||||
function _osem_trywait_err(key,needCount:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq sys_osem_trywait,%rax
|
||||
call fast_syscall
|
||||
end;
|
||||
|
||||
function _osem_wait_err(key,needCount:Integer;pTimeout:PDWORD):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq sys_osem_wait,%rax
|
||||
call fast_syscall
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -6,7 +6,6 @@ unit sys_umtx;
|
|||
interface
|
||||
|
||||
uses
|
||||
errno,
|
||||
time,
|
||||
_umtx;
|
||||
|
||||
|
@ -27,6 +26,7 @@ function _umtx_op_err(obj:Pointer;op:Integer;val:QWORD;uaddr1,uaddr2:Pointer):I
|
|||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
kern_umtx,
|
||||
trap,
|
||||
thr_error;
|
||||
|
|
|
@ -185,6 +185,14 @@
|
|||
<Filename Value="..\kern\kern_osem.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\kern\kern_id.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\sys_osem.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -28,7 +28,9 @@ uses
|
|||
kern_thr,
|
||||
rtprio,
|
||||
kern_condvar,
|
||||
kern_osem;
|
||||
kern_osem,
|
||||
kern_id,
|
||||
sys_osem;
|
||||
|
||||
var
|
||||
mtx:umutex;
|
||||
|
|
Loading…
Reference in New Issue