This commit is contained in:
red-prig 2023-02-23 22:42:17 +03:00
parent c11b5d7271
commit ca6b40ce29
9 changed files with 415 additions and 109 deletions

45
sys/kern_mtx.pas Normal file
View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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>

View File

@ -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);

View File

@ -1,6 +1,7 @@
unit thr;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface

View File

@ -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.

View File

@ -1,6 +1,7 @@
unit vm_machdep;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface