diff --git a/sys/kern_sig.pas b/sys/kern_sig.pas
index 3c474ae4..8a8eded8 100644
--- a/sys/kern_sig.pas
+++ b/sys/kern_sig.pas
@@ -8,6 +8,7 @@ interface
uses
gtailq,
sys_kernel,
+ time,
signal,
signalvar;
@@ -66,12 +67,16 @@ Function sys_sigprocmask(how:Integer;
Function sys_sigpending(oset:p_sigset_t):Integer;
+Function sys_sigwait(oset:p_sigset_t;sig:PInteger):Integer;
+Function sys_sigtimedwait(oset:p_sigset_t;info:p_siginfo_t;timeout:ptimespec):Integer;
+Function sys_sigwaitinfo(oset:p_sigset_t;info:p_siginfo_t):Integer;
+
implementation
uses
ntapi,
systm,
- time,
+ md_psl,
_umtx,
kern_umtx,
kern_time,
@@ -81,8 +86,6 @@ const
max_pending_per_proc=128;
var
- p_p_sigqueue:sigqueue_t;
-
p_pendingcnt :Integer=0;
signal_overflow :Integer=0;
signal_alloc_fail:Integer=0;
@@ -687,8 +690,7 @@ begin
if (td=nil) then Exit(EFAULT);
PROC_LOCK;
- pending:=p_p_sigqueue.sq_signals;
- SIGSETOR(@pending,@td^.td_sigqueue.sq_signals);
+ pending:=td^.td_sigqueue.sq_signals;
PROC_UNLOCK;
Result:=copyout(@pending,oset,sizeof(sigset_t));
@@ -738,7 +740,7 @@ begin
if (sig<>0) and SIGISMEMBER(@waitset,sig) then
begin
- if (sigqueue_get(@td^.td_sigqueue, sig, ksi) <> 0) then
+ if (sigqueue_get(@td^.td_sigqueue,sig,ksi)<>0) then
begin
Result:=0;
break;
@@ -799,19 +801,170 @@ begin
PROC_UNLOCK;
end;
+Function sys_sigwait(oset:p_sigset_t;sig:PInteger):Integer;
+var
+ td:p_kthread;
+ ksi:ksiginfo_t;
+ __set:sigset_t;
+begin
+ td:=curkthread;
+ if (td=nil) then Exit(EFAULT);
+
+ Result:=copyin(oset,@__set,sizeof(sigset_t));
+ if (Result<>0) then Exit(EFAULT);
+
+ Result:=kern_sigtimedwait(td,__set,@ksi,nil);
+ if (Result<>0) then
+ begin
+ if (Result=EINTR) then
+ begin
+ Result:=ERESTART;
+ end;
+ Exit;
+ end;
+
+ Result:=copyout(@ksi.ksi_info.si_signo,sig,sizeof(Integer));
+end;
+
+Function sys_sigtimedwait(oset:p_sigset_t;info:p_siginfo_t;timeout:ptimespec):Integer;
+var
+ td:p_kthread;
+ ts:timespec;
+ ksi:ksiginfo_t;
+ __set:sigset_t;
+begin
+ td:=curkthread;
+ if (td=nil) then Exit(-EFAULT);
+
+ if (timeout<>nil) then
+ begin
+ Result:=copyin(timeout,@ts,sizeof(timespec));
+ if (Result<>0) then Exit(-EFAULT);
+ timeout:=@ts;
+ end;
+
+ Result:=copyin(oset,@__set,sizeof(sigset_t));
+ if (Result<>0) then Exit(-EFAULT);
+
+ Result:=kern_sigtimedwait(td,__set,@ksi,timeout);
+ if (Result<>0) then Exit(-Result);
+
+ if (info<>nil) then
+ begin
+ Result:=copyout(@ksi.ksi_info,info,sizeof(siginfo_t));
+ if (Result<>0) then Exit(-EFAULT);
+ end;
+
+ Result:=ksi.ksi_info.si_signo;
+end;
+
+Function sys_sigwaitinfo(oset:p_sigset_t;info:p_siginfo_t):Integer;
+var
+ td:p_kthread;
+ ksi:ksiginfo_t;
+ __set:sigset_t;
+begin
+ td:=curkthread;
+ if (td=nil) then Exit(-EFAULT);
+
+ Result:=copyin(oset,@__set,sizeof(sigset_t));
+ if (Result<>0) then Exit(-EFAULT);
+
+ Result:=kern_sigtimedwait(td,__set,@ksi,nil);
+ if (Result<>0) then Exit(-Result);
+
+ if (info<>nil) then
+ begin
+ Result:=copyout(@ksi.ksi_info,info,sizeof(siginfo_t));
+ if (Result<>0) then Exit(-EFAULT);
+ end;
+
+ Result:=ksi.ksi_info.si_signo;
+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->td_pcb, PCB_FULL_IRET);
+ end;
+ EJUSTRETURN:;
+ else
+ With td^.td_frame^ do
+ begin
+ tf_rax:=error;
+ tf_rflags:=tf_rflags or PSL_C;
+ end;
+ end;
+end;
+
+function postsig(sig:Integer):Integer; forward;
+
+Function kern_sigsuspend(td:p_kthread;mask:sigset_t):Integer;
+var
+ has_sig,sig:Integer;
+begin
+ PROC_LOCK;
+ kern_sigprocmask(td,SIG_SETMASK,@mask,@td^.td_oldsigmask,SIGPROCMASK_PROC_LOCKED);
+ td^.td_pflags:=td^.td_pflags or TDP_OLDMASK;
+
+ cpu_set_syscall_retval(td,EINTR);
+
+ has_sig:=0;
+ While (has_sig=0) do
+ begin
+ //while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "pause",0) == 0)
+
+ //thread_suspend_check(0);
+
+ mtx_lock(@p_sigacts.ps_mtx);
+
+ repeat
+ sig:=cursig(td,SIG_STOP_ALLOWED);
+ if (sig=0) then Break;
+ has_sig:=has_sig+postsig(sig);
+ until false;
+
+ mtx_unlock(@p_sigacts.ps_mtx);
+ end;
+
+ PROC_UNLOCK;
+ td^.td_errno:=EINTR;
+ td^.td_pflags:=td^.td_pflags or TDP_NERRNO;
+ Result:=EJUSTRETURN;
+end;
+
+//TODO check td_errno,td_oldsigmask,td_retval
+
+function postsig(sig:Integer):Integer;
+begin
+ //TODO
+end;
+
procedure sigexit(td:p_kthread;sig:Integer);
begin
- //
+ //TODO
end;
Function issignal(td:p_kthread;stop_allowed:Integer):Integer;
begin
- //
+ //TODO
end;
procedure reschedule_signals(block:sigset_t;flags:Integer);
begin
- //
+ //TODO
end;
initialization
diff --git a/sys/kern_thread.pas b/sys/kern_thread.pas
index 1077e35a..282c2e19 100644
--- a/sys/kern_thread.pas
+++ b/sys/kern_thread.pas
@@ -114,6 +114,7 @@ type
td_sigstk :stack_t;
td_pflags :Integer;
td_flags :Integer;
+ td_errno :Integer;
td_ref :Integer;
td_priority :Word;
td_pri_class :Word;
@@ -126,8 +127,10 @@ type
td_fsbase :Pointer;
td_cpuset :Ptruint;
td_sigmask :sigset_t;
+ td_oldsigmask :sigset_t;
td_sigqueue :sigqueue_t;
td_frame :p_trapframe;
+ td_retval :array[0..1] of QWORD;
td_kstack :Pointer;
end;
diff --git a/sys/md_psl.pas b/sys/md_psl.pas
new file mode 100644
index 00000000..00a1dbc6
--- /dev/null
+++ b/sys/md_psl.pas
@@ -0,0 +1,33 @@
+unit md_psl;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+const
+ PSL_C =$00000001; // carry bit
+ PSL_PF =$00000004; // parity bit
+ PSL_AF =$00000010; // bcd carry bit
+ PSL_Z =$00000040; // zero bit
+ PSL_N =$00000080; // negative bit
+ PSL_T =$00000100; // trace enable bit
+ PSL_I =$00000200; // interrupt enable bit
+ PSL_D =$00000400; // string instruction direction bit
+ PSL_V =$00000800; // overflow bit
+ PSL_IOPL=$00003000; // i/o privilege level
+ PSL_NT =$00004000; // nested task bit
+ PSL_RF =$00010000; // resume flag bit
+ PSL_AC =$00040000; // alignment checking
+ PSL_ID =$00200000; // identification bit
+
+ PSL_RESERVED_DEFAULT=$00000002;
+
+ PSL_KERNEL=PSL_RESERVED_DEFAULT;
+ PSL_USER =(PSL_RESERVED_DEFAULT or PSL_I);
+
+ PSL_USERCHANGE=(PSL_C or PSL_PF or PSL_AF or PSL_Z or PSL_N or PSL_T or PSL_D or PSL_V or PSL_NT or PSL_RF or PSL_AC or PSL_ID);
+
+implementation
+
+end.
+
diff --git a/sys/test/project1.lpi b/sys/test/project1.lpi
index a94b9657..14b37a2e 100644
--- a/sys/test/project1.lpi
+++ b/sys/test/project1.lpi
@@ -81,6 +81,10 @@
+
+
+
+
diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr
index ee0c9f85..a4a9c958 100644
--- a/sys/test/project1.lpr
+++ b/sys/test/project1.lpr
@@ -15,7 +15,7 @@ uses
kern_rwlock,
thr_private,
kern_sig,
- trap,
+ trap, md_psl,
sysutils,
vulkan,
vDevice;