mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
c11b5d7271
commit
ca6b40ce29
|
@ -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.
|
||||
|
225
sys/kern_sig.pas
225
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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
141
sys/machdep.pas
141
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.
|
||||
|
|
|
@ -97,6 +97,10 @@
|
|||
<Filename Value="..\thr.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\kern_mtx.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
unit thr;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
|
|
14
sys/trap.pas
14
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.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
unit vm_machdep;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
|
|
Loading…
Reference in New Issue