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