mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
3788427643
commit
d59bbaad4e
|
@ -7,7 +7,8 @@ interface
|
|||
|
||||
uses
|
||||
mqueue,
|
||||
LFQueue;
|
||||
LFQueue,
|
||||
kern_mtx;
|
||||
|
||||
type
|
||||
t_callout_func=procedure(arg:Pointer);
|
||||
|
@ -33,6 +34,17 @@ const
|
|||
CALLOUT_SHAREDLOCK =$0020; // callout lock held in shared mode
|
||||
CALLOUT_RWLOCK =$0040; // callout used rw lock
|
||||
|
||||
type
|
||||
p_callout_cpu=^t_callout_cpu;
|
||||
t_callout_cpu=record
|
||||
cc_lock :mtx;
|
||||
cc_curr :p_callout;
|
||||
cc_calllist:TAILQ_HEAD;
|
||||
cc_callfree:TAILQ_HEAD;
|
||||
cc_cancel :Integer;
|
||||
cc_waiting :Integer;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
|
|
|
@ -129,14 +129,25 @@ const
|
|||
type
|
||||
p_teb=^teb;
|
||||
teb=packed record
|
||||
_align1:array[0..23] of QWORD;
|
||||
wow64 :Pointer; //0xC0
|
||||
SEH :Pointer;
|
||||
stack :Pointer;
|
||||
sttop :Pointer;
|
||||
_align1:array[0..20] of QWORD;
|
||||
wow64 :Pointer; //0xC0
|
||||
_align2:array[0..198] of QWORD;
|
||||
thread:Pointer; //0x700
|
||||
tcb :Pointer; //0x708
|
||||
iflag :Integer; //0x710
|
||||
thread :Pointer; //0x700
|
||||
tcb :Pointer; //0x708
|
||||
iflag :Integer; //0x710
|
||||
end;
|
||||
|
||||
const
|
||||
teb_wow64 =ptruint(@teb(nil^).wow64);
|
||||
teb_thread=ptruint(@teb(nil^).thread);
|
||||
|
||||
{$IF teb_wow64 <>$0C0}{$STOP teb_wow64 <>$0C0}{$ENDIF}
|
||||
{$IF teb_thread<>$700}{$STOP teb_thread<>$700}{$ENDIF}
|
||||
|
||||
type
|
||||
t_td_name=array[0..31] of AnsiChar;
|
||||
|
||||
pp_kthread=^p_kthread;
|
||||
|
|
|
@ -117,9 +117,16 @@ end;
|
|||
|
||||
//
|
||||
|
||||
function _thread_null(parameter:pointer):ptrint; register;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
procedure threadinit;
|
||||
begin
|
||||
FillChar(tidhashtbl,SizeOf(tidhashtbl),0);
|
||||
//init internals
|
||||
BeginThread(@_thread_null);
|
||||
end;
|
||||
|
||||
{
|
||||
|
@ -312,6 +319,44 @@ begin
|
|||
HAMT_get_value32(i,@Result);
|
||||
end;
|
||||
|
||||
procedure KernSetThreadDebugName(newtd:p_kthread;prefix:PChar);
|
||||
var
|
||||
td:p_kthread;
|
||||
sttop:Pointer;
|
||||
stack:Pointer;
|
||||
name:shortstring;
|
||||
begin
|
||||
//check stack limits
|
||||
td:=curkthread;
|
||||
if (td<>nil) then
|
||||
begin
|
||||
//in kstack?
|
||||
if (SPtr>td^.td_ksttop) and (SPtr<=td^.td_kstack) then
|
||||
begin
|
||||
//save
|
||||
sttop:=td^.td_teb^.sttop;
|
||||
stack:=td^.td_teb^.stack;
|
||||
//set kstack
|
||||
td^.td_teb^.sttop:=td^.td_ksttop;
|
||||
td^.td_teb^.stack:=td^.td_kstack;
|
||||
end else
|
||||
begin
|
||||
//dont change
|
||||
td:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
name:=shortstring(prefix)+shortstring(newtd^.td_name);
|
||||
SetThreadDebugName(newtd^.td_tid,name);
|
||||
|
||||
if (td<>nil) then
|
||||
begin
|
||||
//restore
|
||||
td^.td_teb^.sttop:=sttop;
|
||||
td^.td_teb^.stack:=stack;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure before_start(td:p_kthread);
|
||||
begin
|
||||
//init this
|
||||
|
@ -461,7 +506,7 @@ begin
|
|||
begin
|
||||
Move(name^,newtd^.td_name,SizeOf(t_td_name));
|
||||
end;
|
||||
SetThreadDebugName(newtd^.td_handle,'ps4:'+newtd^.td_name);
|
||||
KernSetThreadDebugName(newtd,'ps4:');
|
||||
|
||||
sched_fork_thread(td,newtd);
|
||||
|
||||
|
@ -494,8 +539,7 @@ function kthread_add(func,arg:Pointer;newtdp:pp_kthread;name:PChar):Integer;
|
|||
var
|
||||
td:p_kthread;
|
||||
newtd:p_kthread;
|
||||
stack_base:Pointer;
|
||||
stack_size:QWORD;
|
||||
stack:stack_t;
|
||||
|
||||
n:Integer;
|
||||
begin
|
||||
|
@ -514,12 +558,12 @@ begin
|
|||
newtd:=thread_alloc;
|
||||
if (newtd=nil) then Exit(ENOMEM);
|
||||
|
||||
stack_base:=newtd^.td_kstack;
|
||||
stack_size:=(ptruint(newtd^.td_kstack)-ptruint(newtd^.td_ksttop));
|
||||
stack.ss_sp :=newtd^.td_ksttop;
|
||||
stack.ss_size:=(ptruint(newtd^.td_kstack)-ptruint(newtd^.td_ksttop));
|
||||
|
||||
n:=cpu_thread_create(newtd,
|
||||
stack_base,
|
||||
stack_size,
|
||||
stack.ss_sp,
|
||||
stack.ss_size,
|
||||
func,
|
||||
arg);
|
||||
|
||||
|
@ -529,6 +573,8 @@ begin
|
|||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
cpu_set_upcall_kse(newtd,func,arg,@stack);
|
||||
|
||||
if (td<>nil) then
|
||||
begin
|
||||
newtd^.td_sigmask:=td^.td_sigmask;
|
||||
|
@ -542,7 +588,7 @@ begin
|
|||
begin
|
||||
Move(name^,newtd^.td_name,SizeOf(t_td_name));
|
||||
end;
|
||||
SetThreadDebugName(newtd^.td_handle,newtd^.td_name);
|
||||
KernSetThreadDebugName(newtd,'kern:');
|
||||
|
||||
sched_fork_thread(td,newtd);
|
||||
|
||||
|
@ -910,7 +956,7 @@ begin
|
|||
thread_lock(td);
|
||||
|
||||
td^.td_name:=name;
|
||||
SetThreadDebugName(td^.td_handle,'ps4:'+name);
|
||||
KernSetThreadDebugName(td,'ps4:');
|
||||
|
||||
thread_unlock(td);
|
||||
|
||||
|
|
|
@ -6,11 +6,7 @@ unit kern_timeout;
|
|||
interface
|
||||
|
||||
uses
|
||||
windows,
|
||||
|
||||
mqueue,
|
||||
LFQueue,
|
||||
md_sleep,
|
||||
kern_synch,
|
||||
subr_sleepqueue,
|
||||
kern_thr,
|
||||
|
@ -18,20 +14,18 @@ uses
|
|||
kern_rwlock,
|
||||
kern_callout;
|
||||
|
||||
type
|
||||
p_callout_cpu=^t_callout_cpu;
|
||||
t_callout_cpu=record
|
||||
cc_lock :mtx;
|
||||
cc_curr :p_callout;
|
||||
cc_calllist:TAILQ_HEAD;
|
||||
cc_callfree:TAILQ_HEAD;
|
||||
cc_cancel :Integer;
|
||||
cc_waiting :Integer;
|
||||
end;
|
||||
procedure kern_timeout_init();
|
||||
|
||||
procedure CC_LOCK(cc:p_callout_cpu);
|
||||
procedure CC_UNLOCK(cc:p_callout_cpu);
|
||||
procedure CC_LOCK_ASSERT(cc:p_callout_cpu);
|
||||
function callout_lock():p_callout_cpu;
|
||||
procedure callout_cc_del(c:p_callout;cc:p_callout_cpu);
|
||||
|
||||
procedure callout_init (c:p_callout;mpsafe:Integer);
|
||||
procedure _callout_init_lock(c:p_callout;lock:Pointer;flags:Integer);
|
||||
procedure callout_done(c:p_callout);
|
||||
|
||||
procedure softclock_call_cc(c:p_callout;cc:p_callout_cpu);
|
||||
|
||||
function _callout_stop_safe(c:p_callout;safe:Integer):Integer;
|
||||
function callout_reset_on(c:p_callout;to_ticks:Int64;ftn:t_callout_func;arg:Pointer):Integer;
|
||||
|
@ -46,14 +40,11 @@ function callout_reset_curcpu(c:p_callout;on_tick:Int64;fn:t_callout_func;arg:P
|
|||
implementation
|
||||
|
||||
uses
|
||||
kern_thread;
|
||||
md_timeout;
|
||||
|
||||
var
|
||||
timeout_cpu:t_callout_cpu;
|
||||
|
||||
timeout_thr:p_kthread=nil;
|
||||
timeout_new:TIntrusiveMPSCQueue;
|
||||
|
||||
rw_giant:Pointer=nil;
|
||||
|
||||
procedure callout_cpu_init(cc:p_callout_cpu);
|
||||
|
@ -63,21 +54,10 @@ begin
|
|||
TAILQ_INIT(@cc^.cc_callfree);
|
||||
end;
|
||||
|
||||
procedure kern_timeout_callwheel_init();
|
||||
procedure kern_timeout_init();
|
||||
begin
|
||||
callout_cpu_init(@timeout_cpu);
|
||||
end;
|
||||
|
||||
procedure softclock(arg:Pointer); forward;
|
||||
|
||||
procedure start_softclock();
|
||||
var
|
||||
r:Integer;
|
||||
begin
|
||||
timeout_new.Create;
|
||||
|
||||
r:=kthread_add(@softclock,nil,@timeout_thr,'softclock');
|
||||
Assert(r=0,'softclock');
|
||||
md_start_softclock();
|
||||
end;
|
||||
|
||||
procedure callout_init(c:p_callout;mpsafe:Integer);
|
||||
|
@ -91,8 +71,6 @@ begin
|
|||
c^.c_lock :=@rw_giant;
|
||||
c^.c_flags:=CALLOUT_RWLOCK;
|
||||
end;
|
||||
//
|
||||
c^.c_timer:=CreateWaitableTimer(nil,true,nil);
|
||||
end;
|
||||
|
||||
procedure _callout_init_lock(c:p_callout;lock:Pointer;flags:Integer);
|
||||
|
@ -103,13 +81,6 @@ begin
|
|||
Assert((lock<>nil) or ((flags and CALLOUT_RETURNUNLOCKED)=0),'callout_init_lock: CALLOUT_RETURNUNLOCKED with no lock');
|
||||
Assert(lock=nil,'invalid lock');
|
||||
c^.c_flags:=flags and (CALLOUT_RETURNUNLOCKED or CALLOUT_SHAREDLOCK);
|
||||
//
|
||||
c^.c_timer:=CreateWaitableTimer(nil,true,nil);
|
||||
end;
|
||||
|
||||
procedure callout_done(c:p_callout);
|
||||
begin
|
||||
CloseHandle(c^.c_timer);
|
||||
end;
|
||||
|
||||
procedure CC_LOCK(cc:p_callout_cpu); inline;
|
||||
|
@ -133,20 +104,6 @@ begin
|
|||
CC_LOCK(Result);
|
||||
end;
|
||||
|
||||
Procedure wt_timer_add(c:p_callout;cc:p_callout_cpu); forward;
|
||||
|
||||
procedure callout_new_inserted(c:p_callout;cc:p_callout_cpu);
|
||||
begin
|
||||
if (timeout_thr=curkthread) then
|
||||
begin
|
||||
wt_timer_add(c,cc);
|
||||
end else
|
||||
begin
|
||||
timeout_new.Push(c);
|
||||
wakeup_td(timeout_thr);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure callout_cc_add(c:p_callout;cc:p_callout_cpu;to_ticks:Int64;func:t_callout_func;arg:Pointer);
|
||||
begin
|
||||
CC_LOCK_ASSERT(cc);
|
||||
|
@ -163,11 +120,12 @@ begin
|
|||
|
||||
TAILQ_INSERT_TAIL(@cc^.cc_calllist,c,@c^.c_links);
|
||||
|
||||
callout_new_inserted(c,cc);
|
||||
md_callout_new_inserted(c,cc);
|
||||
end;
|
||||
|
||||
procedure callout_cc_del(c:p_callout;cc:p_callout_cpu);
|
||||
begin
|
||||
md_callout_done(c);
|
||||
if ((c^.c_flags and CALLOUT_LOCAL_ALLOC)=0) then Exit;
|
||||
c^.c_func:=nil;
|
||||
TAILQ_INSERT_TAIL(@cc^.cc_callfree,c,@c^.c_links);
|
||||
|
@ -295,71 +253,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure wt_event(arg:Pointer;dwTimerLowValue,dwTimerHighValue:DWORD); stdcall;
|
||||
var
|
||||
c:p_callout;
|
||||
cc:p_callout_cpu;
|
||||
begin
|
||||
if (arg=nil) then Exit;
|
||||
c:=arg;
|
||||
cc:=callout_lock();
|
||||
softclock_call_cc(c,cc);
|
||||
CC_UNLOCK(cc);
|
||||
end;
|
||||
|
||||
Procedure wt_timer_add(c:p_callout;cc:p_callout_cpu);
|
||||
var
|
||||
f:Int64;
|
||||
b:Boolean;
|
||||
begin
|
||||
f:=-c^.c_time;
|
||||
b:=false;
|
||||
|
||||
if ((c^.c_flags and CALLOUT_PENDING)<>0) then
|
||||
begin
|
||||
b:=SetWaitableTimer(c^.c_timer,f,0,@wt_event,c,false);
|
||||
end;
|
||||
|
||||
if not b then
|
||||
begin
|
||||
if (cc^.cc_waiting<>0) then
|
||||
begin
|
||||
cc^.cc_waiting:=0;
|
||||
CC_UNLOCK(cc);
|
||||
wakeup(@cc^.cc_waiting);
|
||||
CC_LOCK(cc);
|
||||
end;
|
||||
|
||||
Assert(((c^.c_flags and CALLOUT_LOCAL_ALLOC)=0) or (c^.c_flags=CALLOUT_LOCAL_ALLOC),'corrupted callout');
|
||||
|
||||
if ((c^.c_flags and CALLOUT_LOCAL_ALLOC)<>0) then
|
||||
begin
|
||||
callout_cc_del(c, cc);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure softclock(arg:Pointer);
|
||||
var
|
||||
c:p_callout;
|
||||
cc:p_callout_cpu;
|
||||
begin
|
||||
repeat
|
||||
cc:=nil;
|
||||
c:=nil;
|
||||
|
||||
while timeout_new.Pop(c) do
|
||||
begin
|
||||
CC_LOCK(cc);
|
||||
wt_timer_add(c,cc);
|
||||
CC_UNLOCK(cc);
|
||||
end;
|
||||
|
||||
msleep_td(0);
|
||||
until false;
|
||||
kthread_exit();
|
||||
end;
|
||||
|
||||
{
|
||||
* New interface; clients allocate their own callout structures.
|
||||
*
|
||||
|
@ -385,7 +278,7 @@ begin
|
|||
|
||||
cc:=callout_lock();
|
||||
|
||||
CancelWaitableTimer(c^.c_timer);
|
||||
md_callout_reset(c);
|
||||
|
||||
if (cc^.cc_curr=c) then
|
||||
begin
|
||||
|
@ -441,7 +334,7 @@ begin
|
|||
again:
|
||||
cc:=callout_lock();
|
||||
|
||||
CancelWaitableTimer(c^.c_timer);
|
||||
md_callout_stop(c);
|
||||
|
||||
if ((c^.c_flags and CALLOUT_PENDING)=0) then
|
||||
begin
|
||||
|
|
|
@ -344,7 +344,7 @@ end;
|
|||
|
||||
function IS_SYSTEM_STACK(td:p_kthread;rsp:qword):Boolean; inline;
|
||||
begin
|
||||
Result:=(rsp<=QWORD(td^.td_kstack)) and (rsp>(QWORD(td^.td_kstack)-SYS_STACK_SIZE));
|
||||
Result:=(rsp<=QWORD(td^.td_kstack)) and (rsp>(QWORD(td^.td_ksttop)));
|
||||
end;
|
||||
|
||||
function IS_SYSCALL(rip:qword):Boolean;
|
||||
|
@ -363,7 +363,11 @@ end;
|
|||
function get_top_mem_td(td:p_kthread;size,align:qword):Pointer;
|
||||
begin
|
||||
Result:=System.Align(td^.td_ksttop,align);
|
||||
if ((Result+size)>=SPtr) then Exit(nil);
|
||||
|
||||
if (SPtr>td^.td_ksttop) and (SPtr<=td^.td_kstack) then
|
||||
begin
|
||||
if ((Result+size)>=SPtr) then Exit(nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _apc_null(dwParam:PTRUINT); stdcall;
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
unit md_timeout;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
windows,
|
||||
|
||||
LFQueue,
|
||||
md_sleep,
|
||||
kern_synch,
|
||||
kern_thr,
|
||||
kern_callout;
|
||||
|
||||
procedure md_start_softclock();
|
||||
procedure md_callout_new_inserted(c:p_callout;cc:p_callout_cpu);
|
||||
procedure md_callout_reset(c:p_callout);
|
||||
procedure md_callout_stop(c:p_callout);
|
||||
procedure md_callout_done(c:p_callout);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
kern_thread,
|
||||
kern_timeout;
|
||||
|
||||
var
|
||||
timeout_thr:p_kthread=nil;
|
||||
timeout_new:TIntrusiveMPSCQueue;
|
||||
|
||||
procedure softclock(arg:Pointer); forward;
|
||||
|
||||
procedure md_start_softclock();
|
||||
var
|
||||
r:Integer;
|
||||
begin
|
||||
timeout_new.Create;
|
||||
|
||||
r:=kthread_add(@softclock,nil,@timeout_thr,'softclock');
|
||||
Assert(r=0,'softclock');
|
||||
end;
|
||||
|
||||
procedure wt_event(arg:Pointer;dwTimerLowValue,dwTimerHighValue:DWORD); stdcall;
|
||||
var
|
||||
c:p_callout;
|
||||
cc:p_callout_cpu;
|
||||
begin
|
||||
if (arg=nil) then Exit;
|
||||
c:=arg;
|
||||
cc:=callout_lock();
|
||||
softclock_call_cc(c,cc);
|
||||
CC_UNLOCK(cc);
|
||||
end;
|
||||
|
||||
Procedure wt_timer_add(c:p_callout;cc:p_callout_cpu);
|
||||
var
|
||||
f:Int64;
|
||||
b:Boolean;
|
||||
begin
|
||||
f:=-c^.c_time;
|
||||
b:=false;
|
||||
|
||||
if ((c^.c_flags and CALLOUT_PENDING)<>0) then
|
||||
begin
|
||||
b:=SetWaitableTimer(c^.c_timer,f,0,@wt_event,c,false);
|
||||
end;
|
||||
|
||||
if not b then
|
||||
begin
|
||||
if (cc^.cc_waiting<>0) then
|
||||
begin
|
||||
cc^.cc_waiting:=0;
|
||||
CC_UNLOCK(cc);
|
||||
wakeup(@cc^.cc_waiting);
|
||||
CC_LOCK(cc);
|
||||
end;
|
||||
|
||||
Assert(((c^.c_flags and CALLOUT_LOCAL_ALLOC)=0) or (c^.c_flags=CALLOUT_LOCAL_ALLOC),'corrupted callout');
|
||||
|
||||
if ((c^.c_flags and CALLOUT_LOCAL_ALLOC)<>0) then
|
||||
begin
|
||||
callout_cc_del(c, cc);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure md_callout_new_inserted(c:p_callout;cc:p_callout_cpu);
|
||||
begin
|
||||
if (timeout_thr=curkthread) then
|
||||
begin
|
||||
wt_timer_add(c,cc);
|
||||
end else
|
||||
begin
|
||||
timeout_new.Push(c);
|
||||
wakeup_td(timeout_thr);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure softclock(arg:Pointer);
|
||||
var
|
||||
c:p_callout;
|
||||
cc:p_callout_cpu;
|
||||
begin
|
||||
repeat
|
||||
cc:=nil;
|
||||
c:=nil;
|
||||
|
||||
while timeout_new.Pop(c) do
|
||||
begin
|
||||
CC_LOCK(cc);
|
||||
wt_timer_add(c,cc);
|
||||
CC_UNLOCK(cc);
|
||||
end;
|
||||
|
||||
msleep_td(0);
|
||||
until false;
|
||||
kthread_exit();
|
||||
end;
|
||||
|
||||
procedure md_callout_reset(c:p_callout);
|
||||
begin
|
||||
if (c^.c_timer=0) then
|
||||
begin
|
||||
c^.c_timer:=CreateWaitableTimer(nil,true,nil);
|
||||
end else
|
||||
begin
|
||||
CancelWaitableTimer(c^.c_timer);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure md_callout_stop(c:p_callout);
|
||||
begin
|
||||
if (c^.c_timer<>0) then
|
||||
begin
|
||||
CancelWaitableTimer(c^.c_timer);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure md_callout_done(c:p_callout);
|
||||
begin
|
||||
if (c^.c_timer<>0) then
|
||||
begin
|
||||
CloseHandle(c^.c_timer);
|
||||
c^.c_timer:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
|
@ -16,6 +16,7 @@ uses
|
|||
kern_thr,
|
||||
kern_thread,
|
||||
kern_sig,
|
||||
kern_timeout,
|
||||
kern_umtx,
|
||||
kern_namedobj,
|
||||
vmount,
|
||||
|
@ -61,6 +62,7 @@ begin
|
|||
threadinit;
|
||||
siginit;
|
||||
umtxq_sysinit;
|
||||
kern_timeout_init;
|
||||
named_table_init;
|
||||
vmountinit;
|
||||
fd_table_init;
|
||||
|
@ -69,7 +71,7 @@ begin
|
|||
selectinit;
|
||||
vntblinit;
|
||||
nameiinit;
|
||||
knote_init();
|
||||
knote_init;
|
||||
vfs_event_init;
|
||||
devfs_mtx_init;
|
||||
devfs_devs_init;
|
||||
|
|
|
@ -561,6 +561,10 @@
|
|||
<Filename Value="..\kern\kern_timeout.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\md\md_timeout.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
Loading…
Reference in New Issue