mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
d5ae7d0c5a
commit
f850dff674
|
@ -91,55 +91,10 @@ var
|
|||
|
||||
init_once:Integer=0;
|
||||
|
||||
procedure THR_LIST_ADD(thrd:p_pthread);
|
||||
procedure THR_LIST_REMOVE(thrd:p_pthread);
|
||||
procedure THR_GCLIST_ADD(thrd:p_pthread);
|
||||
procedure THR_GCLIST_REMOVE(thrd:p_pthread);
|
||||
|
||||
procedure _libpthread_init(curthread:p_pthread);
|
||||
|
||||
implementation
|
||||
|
||||
procedure THR_LIST_ADD(thrd:p_pthread);
|
||||
begin
|
||||
if ((thrd^.tlflags and TLFLAGS_IN_TDLIST)=0) then
|
||||
begin
|
||||
TAILQ_INSERT_HEAD(@_thread_list,@thrd,@thrd^.tle);
|
||||
//_thr_hash_add(thrd);
|
||||
thrd^.tlflags:=thrd^.tlflags or TLFLAGS_IN_TDLIST;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THR_LIST_REMOVE(thrd:p_pthread);
|
||||
begin
|
||||
if (((thrd)^.tlflags and TLFLAGS_IN_TDLIST)<>0) then
|
||||
begin
|
||||
TAILQ_REMOVE(@_thread_list,@thrd,@thrd^.tle);
|
||||
//_thr_hash_remove(thrd);
|
||||
thrd^.tlflags:=thrd^.tlflags and (not TLFLAGS_IN_TDLIST);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THR_GCLIST_ADD(thrd:p_pthread);
|
||||
begin
|
||||
if ((thrd^.tlflags and TLFLAGS_IN_GCLIST)=0) then
|
||||
begin
|
||||
TAILQ_INSERT_HEAD(@_thread_gc_list,@thrd,@thrd^.gcle);
|
||||
thrd^.tlflags:=thrd^.tlflags or TLFLAGS_IN_GCLIST;
|
||||
Inc(_gc_count);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THR_GCLIST_REMOVE(thrd:p_pthread);
|
||||
begin
|
||||
if (((thrd)^.tlflags and TLFLAGS_IN_GCLIST)<>0) then
|
||||
begin
|
||||
TAILQ_REMOVE(@_thread_list,@thrd,@thrd^.gcle);
|
||||
thrd^.tlflags:=thrd^.tlflags and (not TLFLAGS_IN_GCLIST);
|
||||
Dec(_gc_count);
|
||||
end;
|
||||
end;
|
||||
|
||||
const
|
||||
g_user_stacksize=$10000;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ interface
|
|||
|
||||
uses
|
||||
mqueue,
|
||||
time,
|
||||
signal,
|
||||
_umtx;
|
||||
|
||||
|
@ -115,6 +116,7 @@ type
|
|||
child :TProcedure;
|
||||
end;
|
||||
|
||||
p_pthread_attr=^pthread_attr;
|
||||
pthread_attr=packed record
|
||||
sched_policy :Integer;
|
||||
sched_inherit :Integer;
|
||||
|
@ -289,14 +291,49 @@ type
|
|||
sched_priority:Integer;
|
||||
end;
|
||||
|
||||
function TID(thr:p_pthread):Integer; inline;
|
||||
function TID(thr:p_pthread):Integer; inline;
|
||||
|
||||
function SHOULD_CANCEL(thr:p_pthread):Boolean; inline;
|
||||
function THR_SHOULD_GC(thr:p_pthread):Boolean; inline;
|
||||
function THR_IN_CRITICAL(thr:p_pthread):Boolean; inline;
|
||||
function SHOULD_CANCEL(thr:p_pthread):Boolean; inline;
|
||||
function THR_SHOULD_GC(thr:p_pthread):Boolean; inline;
|
||||
function THR_IN_CRITICAL(thr:p_pthread):Boolean; inline;
|
||||
procedure THR_CRITICAL_ENTER(thr:p_pthread); inline;
|
||||
procedure THR_CRITICAL_LEAVE(thr:p_pthread); inline;
|
||||
|
||||
function THR_UMUTEX_TRYLOCK(thr:p_pthread;lck:p_umutex):Integer; inline;
|
||||
function THR_UMUTEX_LOCK(thr:p_pthread;lck:p_umutex):Integer; inline;
|
||||
function THR_UMUTEX_TIMEDLOCK(thr:p_pthread;lck:p_umutex;timo:ptimespec):Integer; inline;
|
||||
function THR_UMUTEX_UNLOCK(thr:p_pthread;lck:p_umutex):Integer; inline;
|
||||
|
||||
procedure THR_LOCK_ACQUIRE(thr:p_pthread;lck:p_umutex); inline;
|
||||
procedure THR_LOCK_ACQUIRE_SPIN(thr:p_pthread;lck:p_umutex); inline;
|
||||
procedure THR_ASSERT_LOCKLEVEL(thr:p_pthread); inline;
|
||||
procedure THR_LOCK_RELEASE(thr:p_pthread;lck:p_umutex); inline;
|
||||
|
||||
procedure THR_LOCK(curthrd:p_pthread); inline;
|
||||
procedure THR_UNLOCK(curthrd:p_pthread); inline;
|
||||
procedure THR_THREAD_LOCK(curthrd,thr:p_pthread); inline;
|
||||
procedure THR_THREAD_UNLOCK(curthrd,thr:p_pthread); inline;
|
||||
|
||||
procedure THREAD_LIST_RDLOCK(curthrd:p_pthread); inline;
|
||||
procedure THREAD_LIST_WRLOCK(curthrd:p_pthread); inline;
|
||||
procedure THREAD_LIST_UNLOCK(curthrd:p_pthread); inline;
|
||||
|
||||
procedure THR_LIST_ADD(thrd:p_pthread);
|
||||
procedure THR_LIST_REMOVE(thrd:p_pthread);
|
||||
procedure THR_GCLIST_ADD(thrd:p_pthread);
|
||||
procedure THR_GCLIST_REMOVE(thrd:p_pthread);
|
||||
|
||||
procedure THR_REF_ADD(curthrd,thrd:p_pthread); inline;
|
||||
procedure THR_REF_DEL(curthrd,thrd:p_pthread); inline;
|
||||
|
||||
function GC_NEEDED:Boolean; inline;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
thr_init,
|
||||
thr_umtx;
|
||||
|
||||
function TID(thr:p_pthread):Integer; inline;
|
||||
begin
|
||||
Result:=thr^.tid;
|
||||
|
@ -322,5 +359,161 @@ begin
|
|||
(thr^.critical_count>0);
|
||||
end;
|
||||
|
||||
procedure THR_CRITICAL_ENTER(thr:p_pthread); inline;
|
||||
begin
|
||||
Inc(thr^.critical_count);
|
||||
end;
|
||||
|
||||
procedure THR_CRITICAL_LEAVE(thr:p_pthread); inline;
|
||||
begin
|
||||
Dec(thr^.critical_count);
|
||||
//_thr_ast(thr);
|
||||
end;
|
||||
|
||||
function THR_UMUTEX_TRYLOCK(thr:p_pthread;lck:p_umutex):Integer; inline;
|
||||
begin
|
||||
Result:=_thr_umutex_trylock(lck,TID(thr));
|
||||
end;
|
||||
|
||||
function THR_UMUTEX_LOCK(thr:p_pthread;lck:p_umutex):Integer; inline;
|
||||
begin
|
||||
Result:=_thr_umutex_lock(lck,TID(thr));
|
||||
end;
|
||||
|
||||
function THR_UMUTEX_TIMEDLOCK(thr:p_pthread;lck:p_umutex;timo:ptimespec):Integer; inline;
|
||||
begin
|
||||
Result:=_thr_umutex_timedlock(lck,TID(thr),timo);
|
||||
end;
|
||||
|
||||
function THR_UMUTEX_UNLOCK(thr:p_pthread;lck:p_umutex):Integer; inline;
|
||||
begin
|
||||
Result:=_thr_umutex_unlock(lck,TID(thr));
|
||||
end;
|
||||
|
||||
procedure THR_LOCK_ACQUIRE(thr:p_pthread;lck:p_umutex); inline;
|
||||
begin
|
||||
Inc(thr^.locklevel);
|
||||
_thr_umutex_lock(lck,TID(thr));
|
||||
end;
|
||||
|
||||
procedure THR_LOCK_ACQUIRE_SPIN(thr:p_pthread;lck:p_umutex); inline;
|
||||
begin
|
||||
Inc(thr^.locklevel);
|
||||
_thr_umutex_lock_spin(lck,TID(thr));
|
||||
end;
|
||||
|
||||
procedure THR_ASSERT_LOCKLEVEL(thr:p_pthread); inline;
|
||||
begin
|
||||
if (thr^.locklevel<=0) then
|
||||
begin
|
||||
//_thr_assert_lock_level();
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THR_LOCK_RELEASE(thr:p_pthread;lck:p_umutex); inline;
|
||||
begin
|
||||
THR_ASSERT_LOCKLEVEL(thr);
|
||||
_thr_umutex_unlock(lck,TID(thr));
|
||||
Dec(thr^.locklevel);
|
||||
//_thr_ast(thr);
|
||||
end;
|
||||
|
||||
procedure THR_LOCK(curthrd:p_pthread); inline;
|
||||
begin
|
||||
THR_LOCK_ACQUIRE(curthrd,@curthrd^.lock);
|
||||
end;
|
||||
|
||||
procedure THR_UNLOCK(curthrd:p_pthread); inline;
|
||||
begin
|
||||
THR_LOCK_RELEASE(curthrd,@curthrd^.lock);
|
||||
end;
|
||||
|
||||
procedure THR_THREAD_LOCK(curthrd,thr:p_pthread); inline;
|
||||
begin
|
||||
THR_LOCK_ACQUIRE(curthrd,@thr^.lock);
|
||||
end;
|
||||
|
||||
procedure THR_THREAD_UNLOCK(curthrd,thr:p_pthread); inline;
|
||||
begin
|
||||
THR_LOCK_RELEASE(curthrd,@thr^.lock);
|
||||
end;
|
||||
|
||||
procedure THREAD_LIST_RDLOCK(curthrd:p_pthread); inline;
|
||||
begin
|
||||
Inc(curthrd^.locklevel);
|
||||
_thr_rwl_rdlock(@_thr_list_lock);
|
||||
end;
|
||||
|
||||
procedure THREAD_LIST_WRLOCK(curthrd:p_pthread); inline;
|
||||
begin
|
||||
Inc(curthrd^.locklevel);
|
||||
_thr_rwl_wrlock(@_thr_list_lock)
|
||||
end;
|
||||
|
||||
procedure THREAD_LIST_UNLOCK(curthrd:p_pthread); inline;
|
||||
begin
|
||||
_thr_rwl_unlock(@_thr_list_lock);
|
||||
Dec(curthrd^.locklevel);
|
||||
//_thr_ast(curthrd);
|
||||
end;
|
||||
|
||||
procedure THR_LIST_ADD(thrd:p_pthread);
|
||||
begin
|
||||
if ((thrd^.tlflags and TLFLAGS_IN_TDLIST)=0) then
|
||||
begin
|
||||
TAILQ_INSERT_HEAD(@_thread_list,@thrd,@thrd^.tle);
|
||||
//_thr_hash_add(thrd);
|
||||
thrd^.tlflags:=thrd^.tlflags or TLFLAGS_IN_TDLIST;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THR_LIST_REMOVE(thrd:p_pthread);
|
||||
begin
|
||||
if (((thrd)^.tlflags and TLFLAGS_IN_TDLIST)<>0) then
|
||||
begin
|
||||
TAILQ_REMOVE(@_thread_list,@thrd,@thrd^.tle);
|
||||
//_thr_hash_remove(thrd);
|
||||
thrd^.tlflags:=thrd^.tlflags and (not TLFLAGS_IN_TDLIST);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THR_GCLIST_ADD(thrd:p_pthread);
|
||||
begin
|
||||
if ((thrd^.tlflags and TLFLAGS_IN_GCLIST)=0) then
|
||||
begin
|
||||
TAILQ_INSERT_HEAD(@_thread_gc_list,@thrd,@thrd^.gcle);
|
||||
thrd^.tlflags:=thrd^.tlflags or TLFLAGS_IN_GCLIST;
|
||||
Inc(_gc_count);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THR_GCLIST_REMOVE(thrd:p_pthread);
|
||||
begin
|
||||
if (((thrd)^.tlflags and TLFLAGS_IN_GCLIST)<>0) then
|
||||
begin
|
||||
TAILQ_REMOVE(@_thread_list,@thrd,@thrd^.gcle);
|
||||
thrd^.tlflags:=thrd^.tlflags and (not TLFLAGS_IN_GCLIST);
|
||||
Dec(_gc_count);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure THR_REF_ADD(curthrd,thrd:p_pthread); inline;
|
||||
begin
|
||||
THR_CRITICAL_ENTER(curthrd);
|
||||
Inc(thrd^.refcount);
|
||||
end;
|
||||
|
||||
procedure THR_REF_DEL(curthrd,thrd:p_pthread); inline;
|
||||
begin
|
||||
Dec(thrd^.refcount);
|
||||
THR_CRITICAL_LEAVE(curthrd);
|
||||
end;
|
||||
|
||||
function GC_NEEDED:Boolean; inline;
|
||||
begin
|
||||
Result:=(_gc_count>=5);
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
unit thr_stack;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
mqueue,
|
||||
pthread_md,
|
||||
thr_private,
|
||||
thr_init;
|
||||
|
||||
procedure _thr_stack_fix_protection(td:p_pthread);
|
||||
function _thr_stack_alloc(attr:p_pthread_attr):Integer;
|
||||
procedure _thr_stack_free(attr:p_pthread_attr);
|
||||
|
||||
implementation
|
||||
|
||||
type
|
||||
//Spare thread stack.
|
||||
p_stack=^t_stack;
|
||||
t_stack=packed record
|
||||
qe :LIST_ENTRY; //Stack queue linkage.
|
||||
stacksize:QWORD; //Stack size (rounded up).
|
||||
guardsize:QWORD; //Guard size.
|
||||
stackaddr:Pointer; //Stack address.
|
||||
end;
|
||||
|
||||
var
|
||||
dstackq :p_stack=nil;
|
||||
mstackq :p_stack=nil;
|
||||
last_stack:Pointer=nil;
|
||||
|
||||
function round_up(size:QWORD):QWORD; inline;
|
||||
begin
|
||||
if ((size mod _thr_page_size)<>0) then
|
||||
begin
|
||||
size:=((size div _thr_page_size)+1)*_thr_page_size;
|
||||
end;
|
||||
Result:=size;
|
||||
end;
|
||||
|
||||
procedure _thr_stack_fix_protection(td:p_pthread);
|
||||
begin
|
||||
//mprotect(td^.attr.stackaddr_attr+
|
||||
// round_up(td^.attr.guardsize_attr),
|
||||
// round_up(td^.attr.stacksize_attr),
|
||||
// _rtld_get_stack_prot);
|
||||
end;
|
||||
|
||||
function _thr_stack_alloc(attr:p_pthread_attr):Integer;
|
||||
var
|
||||
curthread:p_pthread;
|
||||
spare_stack,next:p_stack;
|
||||
stacksize:QWORD;
|
||||
guardsize:QWORD;
|
||||
stackaddr:Pointer;
|
||||
r:Integer;
|
||||
begin
|
||||
curthread:=_get_curthread;
|
||||
|
||||
stacksize:=round_up(attr^.stacksize_attr);
|
||||
guardsize:=round_up(attr^.guardsize_attr);
|
||||
|
||||
attr^.stackaddr_attr:=nil;
|
||||
attr^.flags:=attr^.flags and (not THR_STACK_USER);
|
||||
|
||||
THREAD_LIST_WRLOCK(curthread);
|
||||
|
||||
if ((stacksize=THR_STACK_DEFAULT) and
|
||||
(guardsize=_thr_guard_default)) then
|
||||
begin
|
||||
spare_stack:=LIST_FIRST(@dstackq);
|
||||
if (spare_stack<>nil) then
|
||||
begin
|
||||
LIST_REMOVE(spare_stack,@spare_stack^.qe);
|
||||
attr^.stackaddr_attr:=spare_stack^.stackaddr;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
spare_stack:=LIST_FIRST(@mstackq);
|
||||
While (spare_stack<>nil) do
|
||||
begin
|
||||
next:=LIST_NEXT(spare_stack,@spare_stack^.qe);
|
||||
if (spare_stack^.stacksize=stacksize) and
|
||||
(spare_stack^.guardsize=guardsize) then
|
||||
begin
|
||||
LIST_REMOVE(spare_stack,@spare_stack^.qe);
|
||||
attr^.stackaddr_attr:=spare_stack^.stackaddr;
|
||||
break;
|
||||
end;
|
||||
spare_stack:=next;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (attr^.stackaddr_attr<>nil) then
|
||||
begin
|
||||
THREAD_LIST_UNLOCK(curthread);
|
||||
end else
|
||||
begin
|
||||
if (last_stack=nil) then
|
||||
begin
|
||||
last_stack:=_usrstack-_thr_stack_initial-_thr_guard_default;
|
||||
end;
|
||||
|
||||
stackaddr:=last_stack-stacksize-guardsize;
|
||||
|
||||
last_stack:=last_stack-(stacksize+guardsize);
|
||||
|
||||
THREAD_LIST_UNLOCK(curthread);
|
||||
|
||||
//stackaddr:=mmap(stackaddr,
|
||||
// stacksize+guardsize,
|
||||
// _rtld_get_stack_prot,
|
||||
// MAP_STACK,-1,0
|
||||
// );
|
||||
|
||||
r:=0;
|
||||
if (stackaddr<>Pointer(-1)) then //MAP_FAILED
|
||||
begin
|
||||
//r:=mprotect(stackaddr,guardsize,PROT_NONE);
|
||||
end;
|
||||
|
||||
if (stackaddr<>Pointer(-1)) and //MAP_FAILED
|
||||
((guardsize=0) or (r=0)) then
|
||||
begin
|
||||
//sceKernelSetVirtualRangeName(addr,guardsize,'stack guard');
|
||||
stackaddr:=stackaddr+guardsize;
|
||||
end else
|
||||
begin
|
||||
if (stackaddr<>Pointer(-1)) then //MAP_FAILED
|
||||
begin
|
||||
//munmap(stackaddr,stacksize+guardsize);
|
||||
end;
|
||||
stackaddr:=nil;
|
||||
end;
|
||||
attr^.stackaddr_attr:=stackaddr;
|
||||
end;
|
||||
|
||||
if (attr^.stackaddr_attr<>nil) then
|
||||
Result:=0
|
||||
else
|
||||
Result:=-1;
|
||||
end;
|
||||
|
||||
procedure _thr_stack_free(attr:p_pthread_attr);
|
||||
var
|
||||
spare_stack:p_stack;
|
||||
begin
|
||||
if (attr<>nil) and
|
||||
((attr^.flags and THR_STACK_USER)=0) and
|
||||
(attr^.stackaddr_attr<>nil) then
|
||||
begin
|
||||
spare_stack:=attr^.stackaddr_attr+attr^.stacksize_attr-sizeof(t_stack);
|
||||
spare_stack^.stacksize:=round_up(attr^.stacksize_attr);
|
||||
spare_stack^.guardsize:=round_up(attr^.guardsize_attr);
|
||||
spare_stack^.stackaddr:=attr^.stackaddr_attr;
|
||||
|
||||
if (spare_stack^.stacksize=THR_STACK_DEFAULT) and
|
||||
(spare_stack^.guardsize=_thr_guard_default) then
|
||||
begin
|
||||
LIST_INSERT_HEAD(@dstackq,spare_stack,@spare_stack^.qe);
|
||||
end else
|
||||
begin
|
||||
LIST_INSERT_HEAD(@mstackq,spare_stack,@spare_stack^.qe);
|
||||
end;
|
||||
attr^.stackaddr_attr:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -213,6 +213,10 @@
|
|||
<Filename Value="..\rtprio.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
<Unit>
|
||||
<Filename Value="..\..\kernel\libthr\thr_stack.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
</Unit>
|
||||
</Units>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
|
|
|
@ -31,8 +31,10 @@ uses
|
|||
kern_id,
|
||||
sys_osem,
|
||||
kern_evf,
|
||||
sys_evf, rtprio,
|
||||
pthread;
|
||||
sys_evf,
|
||||
rtprio,
|
||||
pthread,
|
||||
thr_stack;
|
||||
|
||||
var
|
||||
mtx:umutex;
|
||||
|
|
Loading…
Reference in New Issue