diff --git a/sys/kern_mtx.pas b/sys/kern_mtx.pas
new file mode 100644
index 00000000..6636a368
--- /dev/null
+++ b/sys/kern_mtx.pas
@@ -0,0 +1,45 @@
+unit kern_mtx;
+
+{$mode ObjFPC}{$H+}
+{$CALLING SysV_ABI_CDecl}
+
+interface
+
+uses
+ windows,
+ ntapi;
+
+function mtx_init(m:PPointer):Integer;
+function mtx_destroy(m:PPointer):Integer;
+function mtx_lock(m:PPointer):Integer;
+function mtx_unlock(m:PPointer):Integer;
+
+implementation
+
+function mtx_init(m:PPointer):Integer;
+begin
+ Result:=NtCreateMutant(
+ PHandle(m),
+ MUTANT_ALL_ACCESS,
+ nil,
+ False);
+end;
+
+function mtx_destroy(m:PPointer):Integer;
+begin
+ Result:=NtClose(THandle(m^));
+end;
+
+function mtx_lock(m:PPointer):Integer;
+begin
+ Result:=NtWaitForSingleObject(THandle(m^),False,nil);
+end;
+
+function mtx_unlock(m:PPointer):Integer;
+begin
+ Result:=NtReleaseMutant(THandle(m^),nil);
+end;
+
+
+end.
+
diff --git a/sys/kern_sig.pas b/sys/kern_sig.pas
index ab9785df..a91f5774 100644
--- a/sys/kern_sig.pas
+++ b/sys/kern_sig.pas
@@ -76,18 +76,26 @@ Function sys_sigsuspend(sigmask:p_sigset_t):Integer;
Function sys_sigaltstack(ss:p_stack_t;oss:p_stack_t):Integer;
+Function sigonstack(sp:size_t):Integer;
procedure sigqueue_init(list:p_sigqueue);
procedure tdsigcleanup(td:p_kthread);
+procedure tdsignal(td:p_kthread;sig:Integer);
+procedure tdksignal(td:p_kthread;sig:Integer;ksi:p_ksiginfo);
+procedure sigexit(td:p_kthread;sig:Integer);
+
procedure ast;
+function ps_mtx_lock:Integer;
+function ps_mtx_unlock:Integer;
+
implementation
uses
ntapi,
systm,
_umtx,
- kern_umtx,
+ kern_mtx,
kern_time,
vm_machdep,
machdep;
@@ -134,7 +142,7 @@ end;
Function sigqueue_get(sq:p_sigqueue;signo:Integer;si:p_ksiginfo):Integer;
var
- ksi:p_ksiginfo;
+ ksi,next:p_ksiginfo;
count:Integer;
begin
count:=0;
@@ -152,6 +160,7 @@ begin
ksi:=TAILQ_FIRST(@sq^.sq_list);
While (ksi<>nil) do
begin
+ next:=TAILQ_NEXT(ksi,@ksi^.ksi_link);
if (ksi^.ksi_info.si_signo=signo) then
begin
if (count=0) then
@@ -173,7 +182,7 @@ begin
Inc(count);
end;
end;
- ksi:=TAILQ_NEXT(ksi,@ksi^.ksi_link);
+ ksi:=next;
end;
if (count<=1) then
@@ -283,20 +292,21 @@ end;
procedure sigqueue_flush(sq:p_sigqueue);
var
- ksi:p_ksiginfo;
+ ksi,next:p_ksiginfo;
begin
Assert((sq^.sq_flags and SQ_INIT)<>0,'sigqueue not inited');
ksi:=TAILQ_FIRST(@sq^.sq_list);
while (ksi<>nil) do
begin
+ next:=TAILQ_NEXT(ksi,@ksi^.ksi_link);
TAILQ_REMOVE(@sq^.sq_list,ksi,@ksi^.ksi_link);
ksi^.ksi_sigq:=nil;
if ksiginfo_tryfree(ksi) then
begin
Dec(p_pendingcnt);
end;
- ksi:=TAILQ_NEXT(ksi,@ksi^.ksi_link);
+ ksi:=next;
end;
SIGEMPTYSET(@sq^.sq_signals);
@@ -306,7 +316,7 @@ end;
procedure sigqueue_move_set(src,dst:p_sigqueue;_set:p_sigset_t);
var
tmp:sigset_t;
- ksi:p_ksiginfo;
+ ksi,next:p_ksiginfo;
begin
Assert((src^.sq_flags and SQ_INIT)<>0,'sigqueue not inited');
Assert((dst^.sq_flags and SQ_INIT)<>0,'sigqueue not inited');
@@ -314,6 +324,8 @@ begin
ksi:=TAILQ_FIRST(@src^.sq_list);
while (ksi<>nil) do
begin
+ next:=TAILQ_NEXT(ksi,@ksi^.ksi_link);
+
if SIGISMEMBER(_set,ksi^.ksi_info.si_signo) then
begin
TAILQ_REMOVE(@src^.sq_list,ksi,@ksi^.ksi_link);
@@ -321,7 +333,7 @@ begin
ksi^.ksi_sigq:=dst;
end;
- ksi:=TAILQ_NEXT(ksi,@ksi^.ksi_link);
+ ksi:=next;
end;
tmp:=src^.sq_kill;
@@ -337,13 +349,15 @@ end;
procedure sigqueue_delete_set(sq:p_sigqueue;_set:p_sigset_t);
var
- ksi:p_ksiginfo;
+ ksi,next:p_ksiginfo;
begin
Assert((sq^.sq_flags and SQ_INIT)<>0,'sigqueue not inited');
ksi:=TAILQ_FIRST(@sq^.sq_list);
while (ksi<>nil) do
begin
+ next:=TAILQ_NEXT(ksi,@ksi^.ksi_link);
+
if SIGISMEMBER(_set,ksi^.ksi_info.si_signo) then
begin
TAILQ_REMOVE(@sq^.sq_list,ksi,@ksi^.ksi_link);
@@ -354,7 +368,7 @@ begin
end;
end;
- ksi:=TAILQ_NEXT(ksi,@ksi^.ksi_link);
+ ksi:=next;
end;
SIGSETNAND(@sq^.sq_kill,_set);
@@ -470,14 +484,14 @@ begin
end;
end;
-function mtx_lock(m:p_umtx):Integer; inline;
+function ps_mtx_lock:Integer;
begin
- Result:=_sys_umtx_lock(m);
+ Result:=mtx_lock(@p_sigacts.ps_mtx);
end;
-function mtx_unlock(m:p_umtx):Integer; inline;
+function ps_mtx_unlock:Integer;
begin
- Result:=_sys_umtx_unlock(m);
+ Result:=mtx_unlock(@p_sigacts.ps_mtx);
end;
Function kern_sigaction(sig:Integer;
@@ -486,108 +500,108 @@ begin
if (not _SIG_VALID(sig)) then Exit(EINVAL);
PROC_LOCK;
- mtx_lock(@p_sigacts.ps_mtx);
+ ps_mtx_lock;
if (oact<>nil) then
begin
- oact^.sa_mask := p_sigacts.ps_catchmask[_SIG_IDX(sig)];
- oact^.sa_flags := 0;
- if (SIGISMEMBER(@p_sigacts.ps_sigonstack, sig)) then
- oact^.sa_flags := oact^.sa_flags or SA_ONSTACK;
- if (not SIGISMEMBER(@p_sigacts.ps_sigintr, sig)) then
- oact^.sa_flags := oact^.sa_flags or SA_RESTART;
- if (SIGISMEMBER(@p_sigacts.ps_sigreset, sig)) then
- oact^.sa_flags := oact^.sa_flags or SA_RESETHAND;
- if (SIGISMEMBER(@p_sigacts.ps_signodefer, sig)) then
- oact^.sa_flags := oact^.sa_flags or SA_NODEFER;
- if (SIGISMEMBER(@p_sigacts.ps_siginfo, sig)) then
+ oact^.sa_mask:=p_sigacts.ps_catchmask[_SIG_IDX(sig)];
+ oact^.sa_flags:=0;
+ if (SIGISMEMBER(@p_sigacts.ps_sigonstack,sig)) then
+ oact^.sa_flags:=oact^.sa_flags or SA_ONSTACK;
+ if (not SIGISMEMBER(@p_sigacts.ps_sigintr,sig)) then
+ oact^.sa_flags:=oact^.sa_flags or SA_RESTART;
+ if (SIGISMEMBER(@p_sigacts.ps_sigreset,sig)) then
+ oact^.sa_flags:=oact^.sa_flags or SA_RESETHAND;
+ if (SIGISMEMBER(@p_sigacts.ps_signodefer,sig)) then
+ oact^.sa_flags:=oact^.sa_flags or SA_NODEFER;
+ if (SIGISMEMBER(@p_sigacts.ps_siginfo,sig)) then
begin
- oact^.sa_flags := oact^.sa_flags or SA_SIGINFO;
- oact^.u.sa_handler := p_sigacts.ps_sigact[_SIG_IDX(sig)];
+ oact^.sa_flags:=oact^.sa_flags or SA_SIGINFO;
+ oact^.u.sa_handler:=p_sigacts.ps_sigact[_SIG_IDX(sig)];
end else
begin
- oact^.u.sa_handler := p_sigacts.ps_sigact[_SIG_IDX(sig)];
+ oact^.u.sa_handler:=p_sigacts.ps_sigact[_SIG_IDX(sig)];
end;
- if (sig = SIGCHLD and p_sigacts.ps_flag and PS_NOCLDSTOP) then
- oact^.sa_flags := oact^.sa_flags or SA_NOCLDSTOP;
- if (sig = SIGCHLD and p_sigacts.ps_flag and PS_NOCLDWAIT) then
- oact^.sa_flags := oact^.sa_flags or SA_NOCLDWAIT;
+ if (sig=SIGCHLD and p_sigacts.ps_flag and PS_NOCLDSTOP) then
+ oact^.sa_flags:=oact^.sa_flags or SA_NOCLDSTOP;
+ if (sig=SIGCHLD and p_sigacts.ps_flag and PS_NOCLDWAIT) then
+ oact^.sa_flags:=oact^.sa_flags or SA_NOCLDWAIT;
end;
if (act<>nil) then
begin
- if ((sig = SIGKILL) or (sig = SIGSTOP)) and
- (act^.u.code <> SIG_DFL) then
+ if ((sig=SIGKILL) or (sig=SIGSTOP)) and
+ (act^.u.code<>SIG_DFL) then
begin
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
PROC_UNLOCK;
Result:=EINVAL;
end;
- p_sigacts.ps_catchmask[_SIG_IDX(sig)] := act^.sa_mask;
+ p_sigacts.ps_catchmask[_SIG_IDX(sig)]:=act^.sa_mask;
SIG_CANTMASK(@p_sigacts.ps_catchmask[_SIG_IDX(sig)]);
if ((act^.sa_flags and SA_SIGINFO)<>0) then
begin
- p_sigacts.ps_sigact[_SIG_IDX(sig)] := act^.u.sa_handler;
- SIGADDSET(@p_sigacts.ps_siginfo, sig);
+ p_sigacts.ps_sigact[_SIG_IDX(sig)]:=act^.u.sa_handler;
+ SIGADDSET(@p_sigacts.ps_siginfo,sig);
end else
begin
- p_sigacts.ps_sigact[_SIG_IDX(sig)] := act^.u.sa_handler;
- SIGDELSET(@p_sigacts.ps_siginfo, sig);
+ p_sigacts.ps_sigact[_SIG_IDX(sig)]:=act^.u.sa_handler;
+ SIGDELSET(@p_sigacts.ps_siginfo,sig);
end;
if ((act^.sa_flags and SA_RESTART)=0) then
- SIGADDSET(@p_sigacts.ps_sigintr, sig)
+ SIGADDSET(@p_sigacts.ps_sigintr,sig)
else
- SIGDELSET(@p_sigacts.ps_sigintr, sig);
+ SIGDELSET(@p_sigacts.ps_sigintr,sig);
if ((act^.sa_flags and SA_ONSTACK)<>0) then
- SIGADDSET(@p_sigacts.ps_sigonstack, sig)
+ SIGADDSET(@p_sigacts.ps_sigonstack,sig)
else
- SIGDELSET(@p_sigacts.ps_sigonstack, sig);
+ SIGDELSET(@p_sigacts.ps_sigonstack,sig);
if ((act^.sa_flags and SA_RESETHAND)<>0) then
- SIGADDSET(@p_sigacts.ps_sigreset, sig)
+ SIGADDSET(@p_sigacts.ps_sigreset,sig)
else
- SIGDELSET(@p_sigacts.ps_sigreset, sig);
+ SIGDELSET(@p_sigacts.ps_sigreset,sig);
if ((act^.sa_flags and SA_NODEFER)<>0) then
- SIGADDSET(@p_sigacts.ps_signodefer, sig)
+ SIGADDSET(@p_sigacts.ps_signodefer,sig)
else
- SIGDELSET(@p_sigacts.ps_signodefer, sig);
- if (sig = SIGCHLD) then
+ SIGDELSET(@p_sigacts.ps_signodefer,sig);
+ if (sig=SIGCHLD) then
begin
if ((act^.sa_flags and SA_NOCLDSTOP)<>0) then
- p_sigacts.ps_flag := p_sigacts.ps_flag or PS_NOCLDSTOP
+ p_sigacts.ps_flag:=p_sigacts.ps_flag or PS_NOCLDSTOP
else
- p_sigacts.ps_flag := p_sigacts.ps_flag and (not PS_NOCLDSTOP);
+ p_sigacts.ps_flag:=p_sigacts.ps_flag and (not PS_NOCLDSTOP);
if ((act^.sa_flags and SA_NOCLDWAIT)<>0) then
begin
- p_sigacts.ps_flag := p_sigacts.ps_flag or PS_NOCLDWAIT;
+ p_sigacts.ps_flag:=p_sigacts.ps_flag or PS_NOCLDWAIT;
end else
- p_sigacts.ps_flag := p_sigacts.ps_flag and (not PS_NOCLDWAIT);
- if (p_sigacts.ps_sigact[_SIG_IDX(SIGCHLD)] = sig_t(SIG_IGN)) then
- p_sigacts.ps_flag := p_sigacts.ps_flag or PS_CLDSIGIGN
+ p_sigacts.ps_flag:=p_sigacts.ps_flag and (not PS_NOCLDWAIT);
+ if (p_sigacts.ps_sigact[_SIG_IDX(SIGCHLD)]=sig_t(SIG_IGN)) then
+ p_sigacts.ps_flag:=p_sigacts.ps_flag or PS_CLDSIGIGN
else
- p_sigacts.ps_flag := p_sigacts.ps_flag and (not PS_CLDSIGIGN);
+ p_sigacts.ps_flag:=p_sigacts.ps_flag and (not PS_CLDSIGIGN);
end;
- if (p_sigacts.ps_sigact[_SIG_IDX(sig)] = sig_t(SIG_IGN)) or
+ if (p_sigacts.ps_sigact[_SIG_IDX(sig)]=sig_t(SIG_IGN)) or
(((sigprop(sig) and SA_IGNORE)<>0) and
- (p_sigacts.ps_sigact[_SIG_IDX(sig)] = sig_t(SIG_DFL))) then
+ (p_sigacts.ps_sigact[_SIG_IDX(sig)]=sig_t(SIG_DFL))) then
begin
sigqueue_delete_proc(sig);
- if (sig <> SIGCONT) then
+ if (sig<>SIGCONT) then
begin
- SIGADDSET(@p_sigacts.ps_sigignore, sig);
+ SIGADDSET(@p_sigacts.ps_sigignore,sig);
end;
- SIGDELSET(@p_sigacts.ps_sigcatch, sig);
+ SIGDELSET(@p_sigacts.ps_sigcatch,sig);
end else
begin
- SIGDELSET(@p_sigacts.ps_sigignore, sig);
- if (p_sigacts.ps_sigact[_SIG_IDX(sig)] = sig_t(SIG_DFL)) then
- SIGDELSET(@p_sigacts.ps_sigcatch, sig)
+ SIGDELSET(@p_sigacts.ps_sigignore,sig);
+ if (p_sigacts.ps_sigact[_SIG_IDX(sig)]=sig_t(SIG_DFL)) then
+ SIGDELSET(@p_sigacts.ps_sigcatch,sig)
else
- SIGADDSET(@p_sigacts.ps_sigcatch, sig);
+ SIGADDSET(@p_sigacts.ps_sigcatch,sig);
end;
end;
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
PROC_UNLOCK;
Result:=0;
end;
@@ -623,17 +637,17 @@ procedure siginit;
var
i:Integer;
begin
- PROC_LOCK;
+ mtx_init(@p_sigacts.ps_mtx);
For i:=1 to NSIG do
begin
- if ((sigprop(i) and SA_IGNORE)<>0) and (i <> SIGCONT) then
+ if ((sigprop(i) and SA_IGNORE)<>0) and (i<>SIGCONT) then
begin
- SIGADDSET(@p_sigacts.ps_sigignore, i);
+ SIGADDSET(@p_sigacts.ps_sigignore,i);
end;
end;
- PROC_UNLOCK;
+ sigqueue_init(@g_p_sigqueue);
end;
procedure reschedule_signals(block:sigset_t;flags:Integer); forward;
@@ -661,16 +675,16 @@ begin
oset^:=td^.td_sigmask;
end;
- if (_set <> nil) then
+ if (_set<>nil) then
begin
Case how of
SIG_BLOCK:
begin
SIG_CANTMASK(_set);
- oset1 := td^.td_sigmask;
+ oset1:=td^.td_sigmask;
SIGSETOR(@td^.td_sigmask, _set);
- new_block := td^.td_sigmask;
+ new_block:=td^.td_sigmask;
SIGSETNAND(@new_block, @oset1);
end;
SIG_UNBLOCK:
@@ -682,18 +696,18 @@ begin
SIG_SETMASK:
begin
SIG_CANTMASK(_set);
- oset1 := td^.td_sigmask;
+ oset1:=td^.td_sigmask;
if ((flags and SIGPROCMASK_OLD)<>0) then
SIGSETLO(@td^.td_sigmask, _set)
else
- td^.td_sigmask := _set^;
- new_block := td^.td_sigmask;
+ td^.td_sigmask:=_set^;
+ new_block:=td^.td_sigmask;
SIGSETNAND(@new_block, @oset1);
signotify(td);
end;
else
begin
- Result := EINVAL;
+ Result:=EINVAL;
goto _out;
end;
end;
@@ -758,8 +772,6 @@ begin
Result:=copyout(@pending,oset,sizeof(sigset_t));
end;
-procedure sigexit(td:p_kthread;sig:Integer); forward;
-
Function kern_sigtimedwait(td:p_kthread;
waitset:sigset_t;
ksi:p_ksiginfo;
@@ -795,9 +807,9 @@ begin
SIGSETNAND(@td^.td_sigmask,@waitset);
repeat
- mtx_lock(@p_sigacts.ps_mtx);
+ ps_mtx_lock;
sig:=cursig(td,SIG_STOP_ALLOWED);
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
if (sig<>0) and SIGISMEMBER(@waitset,sig) then
begin
@@ -974,7 +986,7 @@ begin
//thread_suspend_check(0);
- mtx_lock(@p_sigacts.ps_mtx);
+ ps_mtx_lock;
repeat
sig:=cursig(td,SIG_STOP_ALLOWED);
@@ -982,7 +994,7 @@ begin
has_sig:=has_sig+postsig(sig);
until false;
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
end;
PROC_UNLOCK;
@@ -1011,7 +1023,7 @@ var
begin
oonstack:=sigonstack(cpu_getstack(td));
- if (oss <> nil) then
+ if (oss<>nil) then
begin
oss^:=td^.td_sigstk;
@@ -1121,14 +1133,14 @@ begin
Assert(_SIG_VALID(sig),'invalid signal');
PROC_LOCK;
- mtx_lock(@p_sigacts.ps_mtx);
+ ps_mtx_lock;
if SIGISMEMBER(@p_sigacts.ps_sigcatch,sig) and
(not SIGISMEMBER(@td^.td_sigmask,sig)) then
begin
sendsig(p_sigacts.ps_sigact[_SIG_IDX(sig)],ksi,@td^.td_sigmask);
postsig_done(sig,td);
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
end else
begin
//ignoring?
@@ -1143,7 +1155,7 @@ begin
p_sigacts.ps_sigact[_SIG_IDX(sig)]:=sig_t(SIG_DFL);
end;
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
tdsendsignal(td,sig,ksi);
end;
@@ -1239,11 +1251,11 @@ begin
sigqueue:=@td^.td_sigqueue;
end;
- mtx_lock(@p_sigacts.ps_mtx);
+ ps_mtx_lock;
if (SIGISMEMBER(@p_sigacts.ps_sigignore,sig)) then
begin
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
if (ksi<>nil) then
if (ksi^.ksi_flags and KSI_INS)<>0 then
@@ -1266,7 +1278,7 @@ begin
else
intrval:=ERESTART;
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
if ((prop and SA_CONT)<>0) then
begin
@@ -1286,6 +1298,21 @@ begin
tdsigwakeup(td,sig,action,intrval);
end;
+procedure tdsignal(td:p_kthread;sig:Integer);
+var
+ ksi:ksiginfo_t;
+begin
+ ksiginfo_init(@ksi);
+ ksi.ksi_info.si_signo:=sig;
+ ksi.ksi_info.si_code :=SI_KERNEL;
+ tdsendsignal(td,sig,@ksi);
+end;
+
+procedure tdksignal(td:p_kthread;sig:Integer;ksi:p_ksiginfo);
+begin
+ tdsendsignal(td,sig,ksi);
+end;
+
procedure forward_signal(td:p_kthread);
begin
//TODO
@@ -1371,7 +1398,7 @@ begin
if ((flags and SIGPROCMASK_PS_LOCKED)=0) then
begin
- mtx_lock(@p_sigacts.ps_mtx);
+ ps_mtx_lock;
end;
if SIGISMEMBER(@p_sigacts.ps_sigcatch,sig) then
@@ -1387,7 +1414,7 @@ begin
if ((flags and SIGPROCMASK_PS_LOCKED)=0) then
begin
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
end;
until false;
end;
@@ -1462,12 +1489,12 @@ begin
begin
if ((prop and SA_STOP)<>0) then
begin
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
PROC_LOCK;
//sig_suspend_threads(td, p, 0);
//thread_suspend_switch(td);
PROC_UNLOCK;
- mtx_lock(@p_sigacts.ps_mtx);
+ ps_mtx_lock;
end else
if ((prop and SA_IGNORE)<>0) then
begin
@@ -1511,19 +1538,19 @@ begin
ksi.ksi_info.si_signo:=sig;
- //if (ksi.ksi_code = SI_TIMER)
+ //if (ksi.ksi_code=SI_TIMER)
// itimer_accept(p, ksi.ksi_timerid, &ksi);
action:=p_sigacts.ps_sigact[_SIG_IDX(sig)];
if (action=sig_t(SIG_DFL)) then
begin
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
sigexit(td,sig);
// NOTREACHED
end else
begin
- Assert((action<>sig_t(SIG_IGN)) and (not SIGISMEMBER(@td^.td_sigmask, sig)),'postsig action');
+ Assert((action<>sig_t(SIG_IGN)) and (not SIGISMEMBER(@td^.td_sigmask,sig)),'postsig action');
if ((td^.td_pflags and TDP_OLDMASK)<>0) then
begin
@@ -1595,7 +1622,7 @@ begin
(not SIGISEMPTY(@g_p_sigqueue.sq_list)) then
begin
PROC_LOCK;
- mtx_lock(@p_sigacts.ps_mtx);
+ ps_mtx_lock;
repeat
sig:=cursig(td,SIG_STOP_ALLOWED);
@@ -1603,7 +1630,7 @@ begin
postsig(sig);
until false;
- mtx_unlock(@p_sigacts.ps_mtx);
+ ps_mtx_unlock;
PROC_UNLOCK;
end;
diff --git a/sys/kern_thread.pas b/sys/kern_thread.pas
index 0c6aebb9..80fa37cf 100644
--- a/sys/kern_thread.pas
+++ b/sys/kern_thread.pas
@@ -130,7 +130,6 @@ type
td_user_pri :Word;
td_name :array[0..31] of AnsiChar;
//
- td_fsbase :Pointer;
td_cpuset :Ptruint;
td_sigmask :sigset_t;
td_oldsigmask :sigset_t;
@@ -179,6 +178,7 @@ procedure thread_free(td:p_kthread);
function sys_thr_new(_param:p_thr_param;_size:Integer):Integer;
function sys_thr_self(id:PQWORD):Integer;
procedure sys_thr_exit(state:PQWORD);
+function sys_thr_kill(id:QWORD;sig:Integer):Integer;
procedure thread_inc_ref(td:p_kthread);
procedure thread_dec_ref(td:p_kthread);
@@ -190,7 +190,7 @@ procedure FOREACH_THREAD_IN_PROC(cb,userdata:Pointer);
function curkthread:p_kthread;
procedure set_curkthread(td:p_kthread);
-function SIGPENDING(td:p_kthread):Boolean; inline;
+function SIGPENDING(td:p_kthread):Boolean;
function TD_IS_RUNNING(td:p_kthread):Boolean; inline;
procedure PROC_LOCK;
@@ -223,6 +223,7 @@ uses
systm,
vm_machdep,
kern_rwlock,
+ kern_mtx,
kern_umtx,
kern_sig;
@@ -247,7 +248,7 @@ asm
movqq td,%gs:(0x700)
end;
-function SIGPENDING(td:p_kthread):Boolean; inline;
+function SIGPENDING(td:p_kthread):Boolean;
begin
Result:=SIGNOTEMPTY(@td^.td_sigqueue.sq_signals) and
sigsetmasked(@td^.td_sigqueue.sq_signals,@td^.td_sigmask);
@@ -260,16 +261,17 @@ end;
procedure PROC_LOCK;
begin
- rw_wlock(p_mtx);
+ mtx_lock(@p_mtx);
end;
procedure PROC_UNLOCK;
begin
- rw_wunlock(p_mtx);
+ mtx_lock(@p_mtx);
end;
procedure threadinit; inline;
begin
+ mtx_init(@p_mtx);
FillChar(tidhashtbl,SizeOf(tidhashtbl),0);
end;
@@ -740,6 +742,70 @@ begin
// NOTREACHED
end;
+type
+ p_t_stk=^_t_stk;
+ _t_stk=record
+ error:Integer;
+ sig:Integer;
+ td:p_kthread;
+ ksi:ksiginfo_t;
+ end;
+
+procedure _for_stk(td:p_kthread;data:p_t_stk); register; //Tfree_data_cb
+begin
+ if (td<>data^.td) then
+ begin
+ data^.error:=0;
+ if (data^.sig=0) then Exit;
+ tdksignal(td,data^.sig,@data^.ksi);
+ end;
+end;
+
+function sys_thr_kill(id:QWORD;sig:Integer):Integer;
+var
+ data:_t_stk;
+begin
+ data.td:=curkthread;
+
+ ksiginfo_init(@data.ksi);
+ data.ksi.ksi_info.si_signo:=sig;
+ data.ksi.ksi_info.si_code :=SI_LWP;
+
+ if (int64(id)=-1) then
+ begin
+ if (sig<>0) and (not _SIG_VALID(sig)) then
+ begin
+ Result:=EINVAL;
+ end else
+ begin
+ data.error:=ESRCH;
+ data.sig:=0;
+ PROC_LOCK;
+ FOREACH_THREAD_IN_PROC(@_for_stk,@data);
+ PROC_UNLOCK;
+ Result:=data.error;
+ end;
+ end else
+ begin
+ Result:=0;
+
+ data.td:=tdfind(DWORD(id));
+ if (data.td=nil) then Exit(ESRCH);
+
+ if (sig=0) then
+ begin
+ //
+ end else
+ if (not _SIG_VALID(sig)) then
+ Result:=EINVAL
+ else
+ tdksignal(data.td,sig,@data.ksi);
+
+ thread_dec_ref(data.td);
+
+ PROC_UNLOCK;
+ end;
+end;
function rtp_to_pri(rtp:p_rtprio;td:p_kthread):Integer;
diff --git a/sys/machdep.pas b/sys/machdep.pas
index ae334930..2399490b 100644
--- a/sys/machdep.pas
+++ b/sys/machdep.pas
@@ -1,23 +1,160 @@
unit machdep;
{$mode ObjFPC}{$H+}
+{$CALLING SysV_ABI_CDecl}
interface
uses
ntapi,
signal,
- signalvar;
+ signalvar,
+ ucontext,
+ kern_thread;
procedure sendsig(catcher:sig_t;ksi:p_ksiginfo;mask:p_sigset_t);
+function sys_sigreturn(sigcntxp:p_ucontext_t):Integer;
implementation
+uses
+ systm,
+ md_psl,
+ kern_sig,
+ trap;
+
procedure sendsig(catcher:sig_t;ksi:p_ksiginfo;mask:p_sigset_t);
+var
+ td:p_kthread;
+ sf:sigframe;
+ sfp:p_sigframe;
+ regs:p_trapframe;
+ sp:QWORD;
+ sig,oonstack:Integer;
begin
- //TODO
+ //char *xfpusave;
+ //size_t xfpusave_len;
+
+ td:=curkthread;
+
+ sig:=ksi^.ksi_info.si_signo;
+
+ //psp:=p_sigacts
+
+ regs:=td^.td_frame;
+ oonstack:=sigonstack(regs^.tf_rsp);
+
+ //if (cpu_max_ext_state_size > sizeof(struct savefpu) && use_xsave) {
+ // xfpusave_len = cpu_max_ext_state_size - sizeof(struct savefpu);
+ // xfpusave = __builtin_alloca(xfpusave_len);
+ //} else {
+ // xfpusave_len = 0;
+ // xfpusave = NULL;
+ //}
+
+ // Save user context.
+ sf:=Default(sigframe);
+
+ sf.sf_uc.uc_sigmask:=mask^;
+ sf.sf_uc.uc_stack :=td^.td_sigstk;
+
+ if ((td^.td_pflags and TDP_ALTSTACK)<>0) then
+ begin
+ if (oonstack<>0) then
+ begin
+ sf.sf_uc.uc_stack.ss_flags:=SS_ONSTACK;
+ end else
+ begin
+ sf.sf_uc.uc_stack.ss_flags:=0;
+ end;
+ end else
+ begin
+ sf.sf_uc.uc_stack.ss_flags:=SS_DISABLE;
+ end;
+
+ sf.sf_uc.uc_mcontext.mc_onstack:=oonstack;
+
+ Move(regs^,sf.sf_uc.uc_mcontext.mc_rdi,SizeOf(trapframe));
+
+ sf.sf_uc.uc_mcontext.mc_len:=sizeof(mcontext_t);
+
+ //get_fpcontext(td, &sf.sf_uc.uc_mcontext, xfpusave, xfpusave_len);
+ //fpstate_drop(td);
+
+ //sf.sf_uc.uc_mcontext.mc_fsbase = pcb->pcb_fsbase;
+ //sf.sf_uc.uc_mcontext.mc_gsbase = pcb->pcb_gsbase;
+
+ if ((td^.td_pflags and TDP_ALTSTACK)<>0) and
+ (oonstack=0) and
+ SIGISMEMBER(@p_sigacts.ps_sigonstack,sig) then
+ begin
+ sp:=QWORD(td^.td_sigstk.ss_sp)+td^.td_sigstk.ss_size;
+ end else
+ begin
+ sp:=regs^.tf_rsp-128;
+ end;
+
+ //if (xfpusave != NULL) {
+ // sp -= xfpusave_len;
+ // sp = (char *)((unsigned long)sp & ~0x3Ful);
+ // sf.sf_uc.uc_mcontext.mc_xfpustate = (register_t)sp;
+ //}
+
+ sp:=sp-sizeof(sigframe);
+
+ sfp:=p_sigframe(sp and (not $F));
+
+ regs^.tf_rdi:=sig;
+ regs^.tf_rdx:=QWORD(@sfp^.sf_uc);
+
+ sf.sf_si:=Default(siginfo_t);
+
+ if (SIGISMEMBER(@p_sigacts.ps_siginfo,sig)) then
+ begin
+ regs^.tf_rsi:=QWORD(@sfp^.sf_si);
+ sf.sf_ahu:=Pointer(catcher);
+
+ sf.sf_si:=ksi^.ksi_info;
+ sf.sf_si.si_signo:=sig;
+
+ regs^.tf_rcx:=QWORD(ksi^.ksi_info.si_addr);
+ end else
+ begin
+ regs^.tf_rsi:=ksi^.ksi_info.si_code;
+ regs^.tf_rcx:=QWORD(ksi^.ksi_info.si_addr);
+ sf.sf_ahu:=Pointer(catcher);
+ end;
+
+ ps_mtx_unlock;
+ PROC_UNLOCK;
+
+ if (copyout(@sf,sfp,sizeof(sigframe))<>0) then
+ begin
+ PROC_LOCK;
+ sigexit(td,SIGILL);
+ end;
+
+ //if (xfpusave != NULL && copyout(xfpusave,
+ // (void *)sf.sf_uc.uc_mcontext.mc_xfpustate, xfpusave_len)
+ // != 0)) {
+ // PROC_LOCK(p);
+ // sigexit(td, SIGILL);
+ //}
+
+ regs^.tf_rsp:=QWORD(sfp);
+ regs^.tf_rip:=QWORD(@sigcode);
+ regs^.tf_rflags:=regs^.tf_rflags and (not (PSL_T or PSL_D));
+
+ set_pcb_flags(td,PCB_FULL_IRET);
+ PROC_LOCK;
+ ps_mtx_lock;
end;
+function sys_sigreturn(sigcntxp:p_ucontext_t):Integer;
+begin
+ //TODO
+ writeln;
+end;
end.
diff --git a/sys/test/project1.lpi b/sys/test/project1.lpi
index bb925556..68450ac9 100644
--- a/sys/test/project1.lpi
+++ b/sys/test/project1.lpi
@@ -97,6 +97,10 @@
+
+
+
+
diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr
index bc5d6cf9..0a953ba4 100644
--- a/sys/test/project1.lpr
+++ b/sys/test/project1.lpr
@@ -16,7 +16,8 @@ uses
kern_rwlock,
thr_private,
kern_sig,
- trap, md_psl,
+ trap,
+ md_psl,
sysutils,
vulkan,
vDevice;
@@ -142,13 +143,27 @@ asm
mov %gs:(0x708),%rax
end;
+procedure __ex_handler(sig,code:Integer;ctx:p_ucontext_t); SysV_ABI_CDecl;
+begin
+ Writeln('__ex_handler:',sig,' ',code);
+end;
+
procedure test_thread; sysv_abi_default;
var
rax:qword;
+ act:sigaction_t;
begin
//SetTlsBase(Pointer(qword(1)));
+ act:=Default(sigaction_t);
+ act.u.sa_handler:=sa_handler(@__ex_handler);
+ act.sa_flags:=SA_RESTART;
+
+ sys_sigaction(SIGUSR1,@act,nil,0);
+
+ sys_thr_kill(curkthread^.td_tid,SIGUSR1);
+
sig_lock;
sig_lock;
sleep(1);
diff --git a/sys/thr.pas b/sys/thr.pas
index ecf43608..4f4fc9a1 100644
--- a/sys/thr.pas
+++ b/sys/thr.pas
@@ -1,6 +1,7 @@
unit thr;
{$mode ObjFPC}{$H+}
+{$CALLING SysV_ABI_CDecl}
interface
diff --git a/sys/trap.pas b/sys/trap.pas
index ae2e09d9..b8643350 100644
--- a/sys/trap.pas
+++ b/sys/trap.pas
@@ -97,10 +97,12 @@ procedure _sig_unlock;
procedure sig_unlock;
procedure fast_syscall;
+procedure sigcode;
implementation
uses
+ machdep,
vm_machdep,
kern_sig;
@@ -149,7 +151,7 @@ asm
popq %rbp
end;
-procedure set_pcb_flags(td:p_kthread;f:Integer); inline;
+procedure set_pcb_flags(td:p_kthread;f:Integer);
begin
td^.pcb_flags:=f;
end;
@@ -352,7 +354,15 @@ asm
//restore rip
end;
-
+procedure sigcode; assembler; nostackframe;
+asm
+ call sigframe.sf_ahu(%rsp)
+ lea sigframe.sf_uc(%rsp),%rdi
+ pushq $0
+ movqq sys_sigreturn,%rax
+ call fast_syscall
+ hlt
+end;
end.
diff --git a/sys/vm_machdep.pas b/sys/vm_machdep.pas
index afc2bd9f..b13343d3 100644
--- a/sys/vm_machdep.pas
+++ b/sys/vm_machdep.pas
@@ -1,6 +1,7 @@
unit vm_machdep;
{$mode ObjFPC}{$H+}
+{$CALLING SysV_ABI_CDecl}
interface