mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
e68bf7838b
commit
fce9f80df0
|
@ -12,14 +12,21 @@ function sys_getcontext(ucp:p_ucontext_t):Integer;
|
|||
function sys_setcontext(ucp:p_ucontext_t):Integer;
|
||||
function sys_swapcontext(oucp,ucp:p_ucontext_t):Integer;
|
||||
|
||||
function sys_thr_get_ucontext(tid:Integer;ucp:p_ucontext_t):Integer;
|
||||
function sys_thr_suspend_ucontext(tid:Integer):Integer;
|
||||
function sys_thr_resume_ucontext(tid:Integer):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
systm,
|
||||
kern_thr,
|
||||
kern_thread,
|
||||
signal,
|
||||
kern_sig,
|
||||
kern_synch,
|
||||
sched_ule,
|
||||
machdep;
|
||||
|
||||
{
|
||||
|
@ -108,6 +115,202 @@ begin
|
|||
if (Result=0) then Exit(EJUSTRETURN);
|
||||
end;
|
||||
|
||||
function sys_thr_get_ucontext(tid:Integer;ucp:p_ucontext_t):Integer;
|
||||
var
|
||||
tdf:p_kthread;
|
||||
uc:ucontext_t;
|
||||
begin
|
||||
tdf:=tdfind(tid);
|
||||
|
||||
repeat
|
||||
if (tdf=nil) then Exit(ESRCH);
|
||||
|
||||
PROC_LOCK;
|
||||
thread_lock(tdf);
|
||||
|
||||
if ((tdf^.td_inhibitors and TDI_SUSP_CTX)=0) and
|
||||
((tdf^.td_flags and TDF_SUSP_CTX)=0) then
|
||||
begin
|
||||
thread_unlock(tdf);
|
||||
thread_dec_ref(tdf);
|
||||
PROC_UNLOCK;
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
case tdf^.td_state of
|
||||
TDS_INACTIVE :; //try again?
|
||||
TDS_INHIBITED:
|
||||
begin
|
||||
bzero(@uc,SizeOf(ucontext_t));
|
||||
|
||||
get_mcontext2(tdf, @uc.uc_mcontext, 0);
|
||||
|
||||
thread_unlock(tdf);
|
||||
thread_dec_ref(tdf);
|
||||
PROC_UNLOCK;
|
||||
|
||||
Result:=copyout(@uc,ucp,UC_COPY_SIZE);
|
||||
Exit;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Writeln('get_ucontext: an illegal state ',tdf^.td_state);
|
||||
thread_unlock(tdf);
|
||||
thread_dec_ref(tdf);
|
||||
PROC_UNLOCK;
|
||||
Exit(ESRCH);
|
||||
end;
|
||||
end;
|
||||
|
||||
thread_unlock(tdf);
|
||||
thread_dec_ref(tdf);
|
||||
PROC_UNLOCK;
|
||||
|
||||
pause('ususp',1);
|
||||
tdf:=tdfind(tid);
|
||||
until false;
|
||||
end;
|
||||
|
||||
function sys_thr_suspend_ucontext(tid:Integer):Integer;
|
||||
label
|
||||
_exit;
|
||||
var
|
||||
td,tdf,tdf2:p_kthread;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
td:=curkthread;
|
||||
if (td=nil) then Exit(-1);
|
||||
|
||||
if (tid=td^.td_tid) then Exit(EDEADLK);
|
||||
|
||||
tdf:=tdfind(tid);
|
||||
|
||||
if (tdf=nil) then Exit(ESRCH);
|
||||
|
||||
PROC_LOCK;
|
||||
thread_lock(tdf);
|
||||
|
||||
if ((tdf^.td_inhibitors and TDI_SUSP_CTX)=0) and
|
||||
((tdf^.td_flags and TDF_SUSP_CTX)=0) then
|
||||
begin
|
||||
if ((tdf^.td_inhibitors and TDI_SLEEPING)=0) or
|
||||
((tdf^.td_flags and TDF_SINTR)=0) then
|
||||
begin
|
||||
tdf^.td_flags:=tdf^.td_flags or (TDF_ASTPENDING or TDF_SUSP_CTX);
|
||||
|
||||
if TD_IS_RUNNING(td) then
|
||||
begin
|
||||
forward_signal(td);
|
||||
end;
|
||||
|
||||
repeat
|
||||
if (tdf^.td_state<>TDS_RUNQ) and
|
||||
((tdf^.td_inhibitors and TDI_SLEEPING)=0) then
|
||||
begin
|
||||
Result:=0;
|
||||
goto _exit;
|
||||
end;
|
||||
|
||||
thread_unlock(tdf);
|
||||
thread_dec_ref(tdf);
|
||||
PROC_UNLOCK;
|
||||
|
||||
pause('ususp',1);
|
||||
|
||||
tdf2:=tdfind(tid);
|
||||
|
||||
if (tdf2=nil) then Exit(ESRCH);
|
||||
|
||||
if (tdf<>tdf2) then
|
||||
begin
|
||||
thread_dec_ref(tdf2);
|
||||
Exit(ESRCH);
|
||||
end;
|
||||
|
||||
PROC_LOCK;
|
||||
thread_lock(tdf);
|
||||
|
||||
until not (((tdf^.td_inhibitors and TDI_SLEEPING)=0) or
|
||||
((tdf^.td_flags and TDF_SINTR)=0));
|
||||
|
||||
tdf^.td_flags:=tdf^.td_flags and (not (TDF_ASTPENDING or TDF_SUSP_CTX));
|
||||
tdf^.td_state:=TDS_INHIBITED;
|
||||
tdf^.td_inhibitors:=tdf^.td_inhibitors or TDI_SUSP_CTX;
|
||||
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
tdf^.td_state:=TDS_INHIBITED;
|
||||
tdf^.td_inhibitors:=tdf^.td_inhibitors or TDI_SUSP_CTX;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
end;
|
||||
|
||||
_exit:
|
||||
thread_unlock(tdf);
|
||||
thread_dec_ref(tdf);
|
||||
PROC_UNLOCK;
|
||||
end;
|
||||
|
||||
function sys_thr_resume_ucontext(tid:Integer):Integer;
|
||||
label
|
||||
_exit;
|
||||
var
|
||||
td,tdf:p_kthread;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
td:=curkthread;
|
||||
if (td=nil) then Exit(-1);
|
||||
|
||||
if (tid=td^.td_tid) then Exit(EINVAL);
|
||||
|
||||
tdf:=tdfind(tid);
|
||||
|
||||
if (tdf=nil) then Exit(ESRCH);
|
||||
|
||||
PROC_LOCK;
|
||||
thread_lock(tdf);
|
||||
|
||||
if ((tdf^.td_inhibitors and TDI_SUSP_CTX)=0) then
|
||||
begin
|
||||
if ((tdf^.td_flags and TDF_SUSP_CTX)=0) then
|
||||
begin
|
||||
Result:=EINVAL;
|
||||
goto _exit;
|
||||
end;
|
||||
tdf^.td_flags:=tdf^.td_flags and (not TDF_SUSP_CTX);
|
||||
end else
|
||||
begin
|
||||
if ((tdf^.td_flags and TDF_SUSP_CTX)<>0) then
|
||||
begin
|
||||
tdf^.td_flags:=tdf^.td_flags and (not TDF_SUSP_CTX);
|
||||
Result:=0;
|
||||
goto _exit;
|
||||
end;
|
||||
|
||||
tdf^.td_inhibitors:=tdf^.td_inhibitors and (not TDI_SUSP_CTX);
|
||||
|
||||
if (tdf^.td_inhibitors=0) then
|
||||
begin
|
||||
tdf^.td_state:=TDS_CAN_RUN;
|
||||
end;
|
||||
|
||||
setrunnable(tdf);
|
||||
end;
|
||||
|
||||
Result:=0;
|
||||
|
||||
_exit:
|
||||
thread_unlock(tdf);
|
||||
thread_dec_ref(tdf);
|
||||
PROC_UNLOCK;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
|
|
@ -79,6 +79,7 @@ procedure tdsigcleanup(td:p_kthread);
|
|||
|
||||
procedure tdsignal(td:p_kthread;sig:Integer);
|
||||
procedure tdksignal(td:p_kthread;sig:Integer;ksi:p_ksiginfo);
|
||||
procedure forward_signal(td:p_kthread);
|
||||
procedure sigexit(td:p_kthread;sig:Integer);
|
||||
|
||||
Function cursig(td:p_kthread;stop_allowed:Integer):Integer;
|
||||
|
@ -1732,10 +1733,19 @@ begin
|
|||
td:=curkthread;
|
||||
|
||||
thread_lock(td);
|
||||
|
||||
flags:=td^.td_flags;
|
||||
|
||||
td^.td_flags:=td^.td_flags and (not (TDF_ASTPENDING or TDF_NEEDSIGCHK or TDF_NEEDSUSPCHK or
|
||||
TDF_NEEDRESCHED or TDF_ALRMPEND or TDF_PROFPEND or TDF_MACPEND));
|
||||
td^.td_flags:=flags and
|
||||
(not (
|
||||
TDF_ASTPENDING or
|
||||
TDF_NEEDSUSPCHK or
|
||||
TDF_NEEDRESCHED or
|
||||
TDF_NEEDSIGCHK or
|
||||
TDF_ALRMPEND or
|
||||
TDF_PROFPEND or
|
||||
TDF_MACPEND
|
||||
));
|
||||
|
||||
thread_unlock(td);
|
||||
|
||||
|
@ -1759,8 +1769,8 @@ begin
|
|||
begin
|
||||
thread_lock(td);
|
||||
sched_prio(td,td^.td_user_pri);
|
||||
mi_switch(SW_INVOL or SWT_NEEDRESCHED);
|
||||
thread_unlock(td);
|
||||
mi_switch(SW_INVOL or SWT_NEEDRESCHED);
|
||||
end;
|
||||
|
||||
if ((flags and TDF_NEEDSIGCHK)<>0) or
|
||||
|
@ -1792,6 +1802,34 @@ begin
|
|||
td^.td_pflags:=td^.td_pflags and (not TDP_OLDMASK);
|
||||
kern_sigprocmask(td,SIG_SETMASK,@td^.td_oldsigmask,nil,0);
|
||||
end;
|
||||
|
||||
if ((flags and TDF_SUSP_CTX)<>0) then
|
||||
begin
|
||||
// context suspend
|
||||
thread_lock(td);
|
||||
|
||||
//recheck?
|
||||
if ((td^.td_flags and TDF_SUSP_CTX)<>0) then
|
||||
begin
|
||||
td^.td_flags:=td^.td_flags and (not TDF_SUSP_CTX);
|
||||
td^.td_state:=TDS_INHIBITED;
|
||||
td^.td_inhibitors:=td^.td_inhibitors or TDI_SUSP_CTX;
|
||||
thread_unlock(td);
|
||||
|
||||
mi_switch(SW_VOL or SWT_SUSPEND);
|
||||
end else
|
||||
begin
|
||||
thread_unlock(td);
|
||||
end;
|
||||
end;
|
||||
|
||||
if ((td^.td_flags and TDF_ASTPENDING)=0) then
|
||||
begin
|
||||
thread_lock(td);
|
||||
td^.td_flags:=td^.td_flags and (not TDF_UNUSED09); //sony ext????
|
||||
thread_unlock(td);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
@ -41,6 +41,8 @@ function tsleep(ident :Pointer;
|
|||
wmesg :PChar;
|
||||
timo :Int64):Integer; inline;
|
||||
|
||||
function pause(wmesg:PChar;timo:Int64):Integer;
|
||||
|
||||
procedure wakeup(ident:Pointer);
|
||||
procedure wakeup_one(ident:Pointer);
|
||||
function mi_switch(flags:Integer):Integer;
|
||||
|
@ -59,6 +61,9 @@ uses
|
|||
md_sleep,
|
||||
rtprio;
|
||||
|
||||
var
|
||||
pause_wchan:Integer=0;
|
||||
|
||||
function msleep(ident :Pointer;
|
||||
lock :p_mtx;
|
||||
priority:Integer;
|
||||
|
@ -76,7 +81,10 @@ begin
|
|||
if (TD_ON_SLEEPQ(td)) then
|
||||
sleepq_remove(td,td^.td_wchan);
|
||||
|
||||
flags:=SLEEPQ_SLEEP;
|
||||
if (ident=@pause_wchan) then
|
||||
flags:=SLEEPQ_PAUSE
|
||||
else
|
||||
flags:=SLEEPQ_SLEEP;
|
||||
|
||||
if (catch<>0) then
|
||||
flags:=flags or SLEEPQ_INTERRUPTIBLE;
|
||||
|
@ -119,6 +127,14 @@ begin
|
|||
Result:=msleep(ident,nil,priority,wmesg,timo);
|
||||
end;
|
||||
|
||||
function pause(wmesg:PChar;timo:Int64):Integer;
|
||||
begin
|
||||
// silently convert invalid timeouts
|
||||
if (timo < 1) then timo:=1;
|
||||
|
||||
Result:=(tsleep(@pause_wchan, 0, wmesg, timo));
|
||||
end;
|
||||
|
||||
procedure wakeup(ident:Pointer);
|
||||
begin
|
||||
sleepq_lock(ident);
|
||||
|
@ -156,10 +172,21 @@ begin
|
|||
case (flags and SW_TYPE_MASK) of
|
||||
SWT_RELINQUISH,
|
||||
SWT_NEEDRESCHED:
|
||||
begin
|
||||
md_yield;
|
||||
end;
|
||||
SWT_SLEEPQ,
|
||||
SWT_SLEEPQTIMO:
|
||||
begin
|
||||
if (td=nil) then Exit(-1);
|
||||
Result:=sched_switch(td);
|
||||
end;
|
||||
SWT_SUSPEND:
|
||||
begin
|
||||
if (td=nil) then Exit(-1);
|
||||
td^.td_slptick:=0; //infinite
|
||||
Result:=sched_switch(td);
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
|
|
@ -95,6 +95,8 @@ const
|
|||
TDI_LOCK =$0008; // Stopped on a lock.
|
||||
TDI_IWAIT =$0010; // Awaiting interrupt.
|
||||
|
||||
TDI_SUSP_CTX =$0020; // Sony extension
|
||||
|
||||
THR_SUSPENDED =$0001;
|
||||
|
||||
// These flags are kept in p_flag.
|
||||
|
@ -117,6 +119,7 @@ const
|
|||
SWT_REMOTEPREEMPT =11; // Remote processor preempted.
|
||||
SWT_REMOTEWAKEIDLE=12; // Remote processor preempted idle.
|
||||
SWT_COUNT =13; // Number of switch types.
|
||||
|
||||
// Flags
|
||||
SW_VOL =$0100; // Voluntary switch.
|
||||
SW_INVOL =$0200; // Involuntary switch.
|
||||
|
@ -184,7 +187,7 @@ type
|
|||
ru_nvcsw :Int64;
|
||||
ru_nivcsw :Int64;
|
||||
end;
|
||||
td_timeo :Int64;
|
||||
td_slptick :Int64;
|
||||
//
|
||||
td_fpop :Pointer;
|
||||
td_map_def_user :Pointer;
|
||||
|
|
|
@ -26,6 +26,7 @@ procedure cpu_set_syscall_retval(td:p_kthread;error:Integer);
|
|||
procedure cpu_set_upcall_kse(td:p_kthread;entry,arg:Pointer;stack:p_stack_t);
|
||||
|
||||
function get_mcontext(td:p_kthread;mcp:p_mcontext_t;flags:Integer):Integer;
|
||||
function get_mcontext2(td:p_kthread;mcp:p_mcontext_t;flags:Integer):Integer;
|
||||
function set_mcontext(td:p_kthread;mcp:p_mcontext_t):Integer;
|
||||
|
||||
procedure sendsig(catcher:sig_t;ksi:p_ksiginfo;mask:p_sigset_t);
|
||||
|
@ -224,6 +225,57 @@ begin
|
|||
Result:=0;
|
||||
end;
|
||||
|
||||
//sce ext
|
||||
|
||||
function get_mcontext2(td:p_kthread;mcp:p_mcontext_t;flags:Integer):Integer;
|
||||
var
|
||||
tp:p_trapframe;
|
||||
begin
|
||||
tp:=td^.td_frame;
|
||||
|
||||
mcp^.mc_onstack:=sigonstack(tp^.tf_rsp);
|
||||
|
||||
mcp^.mc_r15 :=tp^.tf_r15;
|
||||
mcp^.mc_r14 :=tp^.tf_r14;
|
||||
mcp^.mc_r13 :=tp^.tf_r13;
|
||||
mcp^.mc_r12 :=tp^.tf_r12;
|
||||
mcp^.mc_r11 :=tp^.tf_r11;
|
||||
mcp^.mc_r10 :=tp^.tf_r10;
|
||||
mcp^.mc_r9 :=tp^.tf_r9;
|
||||
mcp^.mc_r8 :=tp^.tf_r8;
|
||||
mcp^.mc_rdi :=tp^.tf_rdi;
|
||||
mcp^.mc_rsi :=tp^.tf_rsi;
|
||||
mcp^.mc_rbp :=tp^.tf_rbp;
|
||||
mcp^.mc_rbx :=tp^.tf_rbx;
|
||||
mcp^.mc_rcx :=tp^.tf_rcx;
|
||||
mcp^.mc_rflags:=tp^.tf_rflags;
|
||||
mcp^.mc_rax :=tp^.tf_rax;
|
||||
mcp^.mc_rdx :=tp^.tf_rdx;
|
||||
mcp^.mc_rip :=tp^.tf_rip;
|
||||
mcp^.mc_cs :=tp^.tf_cs;
|
||||
mcp^.mc_rsp :=tp^.tf_rsp;
|
||||
mcp^.mc_ss :=tp^.tf_ss;
|
||||
mcp^.mc_ds :=tp^.tf_ds;
|
||||
mcp^.mc_es :=tp^.tf_es;
|
||||
mcp^.mc_fs :=tp^.tf_fs;
|
||||
mcp^.mc_gs :=tp^.tf_gs;
|
||||
mcp^.mc_flags :=tp^.tf_flags;
|
||||
mcp^.mc_len :=sizeof(mcontext_t);
|
||||
|
||||
//xmm,ymm
|
||||
get_fpcontext(td,mcp,@mcp^.mc_fpstate);
|
||||
//xmm,ymm
|
||||
|
||||
mcp^.mc_fsbase:=ptruint(td^.pcb_fsbase);
|
||||
mcp^.mc_gsbase:=ptruint(td^.pcb_gsbase);
|
||||
|
||||
bzero(@mcp^.mc_spare,sizeof(mcp^.mc_spare));
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
//sce ext
|
||||
|
||||
function set_mcontext(td:p_kthread;mcp:p_mcontext_t):Integer;
|
||||
var
|
||||
tp:p_trapframe;
|
||||
|
|
|
@ -24,6 +24,7 @@ function setrunnable(td:p_kthread):Integer;
|
|||
implementation
|
||||
|
||||
uses
|
||||
atomic,
|
||||
md_sleep,
|
||||
md_thread;
|
||||
|
||||
|
@ -98,12 +99,12 @@ end;
|
|||
|
||||
function sched_switch(td:p_kthread):Integer;
|
||||
var
|
||||
td_timeo:Int64;
|
||||
slptick:Int64;
|
||||
begin
|
||||
td^.td_flags:=td^.td_flags and (not (TDF_NEEDRESCHED or TDF_SLICEEND));
|
||||
atomic_clear_int(@td^.td_flags,TDF_NEEDRESCHED or TDF_SLICEEND);
|
||||
|
||||
td_timeo:=System.InterlockedExchange64(td^.td_timeo,0);
|
||||
Result:=msleep_td(td_timeo);
|
||||
slptick:=System.InterlockedExchange64(td^.td_slptick,0);
|
||||
Result:=msleep_td(slptick);
|
||||
end;
|
||||
|
||||
function setrunnable(td:p_kthread):Integer;
|
||||
|
|
|
@ -215,7 +215,7 @@ begin
|
|||
Assert(td^.td_sleepqueue=nil);
|
||||
Assert(wchan<>nil);
|
||||
|
||||
td^.td_timeo:=time;
|
||||
td^.td_slptick:=time;
|
||||
end;
|
||||
|
||||
function sleepq_sleepcnt(wchan,lock:Pointer;flags,queue:Integer):DWORD;
|
||||
|
|
|
@ -12,10 +12,10 @@ uses
|
|||
|
||||
function _umtxq_alloc:THandle;
|
||||
procedure _umtxq_free(h:THandle);
|
||||
function msleep_umtxq(h:THandle;timo:Int64):Integer; inline;
|
||||
function msleep_umtxq(h:THandle;timo:Int64):Integer;
|
||||
function wakeup_umtxq(h:THandle):Integer; inline;
|
||||
|
||||
function msleep_td(timo:Int64):Integer; inline;
|
||||
function msleep_td(timo:Int64):Integer;
|
||||
function wakeup_td(td:p_kthread):Integer; inline;
|
||||
procedure md_yield; inline;
|
||||
|
||||
|
@ -66,7 +66,7 @@ begin
|
|||
NtClose(h);
|
||||
end;
|
||||
|
||||
function msleep_umtxq(h:THandle;timo:Int64):Integer; inline;
|
||||
function msleep_umtxq(h:THandle;timo:Int64):Integer;
|
||||
begin
|
||||
if (timo=0) then
|
||||
begin
|
||||
|
@ -85,7 +85,7 @@ begin
|
|||
Result:=ntw2px(NtSetEvent(h,nil));
|
||||
end;
|
||||
|
||||
function msleep_td(timo:Int64):Integer; inline;
|
||||
function msleep_td(timo:Int64):Integer;
|
||||
begin
|
||||
if (timo=0) then
|
||||
begin
|
||||
|
|
Loading…
Reference in New Issue