mirror of https://github.com/red-prig/fpPS4.git
225 lines
5.4 KiB
Plaintext
225 lines
5.4 KiB
Plaintext
unit thr_init;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
{$CALLING SysV_ABI_CDecl}
|
|
|
|
interface
|
|
|
|
uses
|
|
mqueue,
|
|
syscalls,
|
|
time,
|
|
pthread,
|
|
pthread_md,
|
|
thr_umtx,
|
|
thr_private;
|
|
|
|
var
|
|
_usrstack :Pointer=Pointer($FFFFFFEFFF); //USRSTACK kern.usrstack
|
|
_thr_initial :p_pthread;
|
|
_thread_event_mask :Integer;
|
|
_thread_last_event :p_pthread;
|
|
_thread_list :pthreadlist=(tqh_first:nil;tqh_last:@_thread_list.tqh_first);
|
|
_thread_gc_list :pthreadlist=(tqh_first:nil;tqh_last:@_thread_gc_list.tqh_first);
|
|
_thread_active_threads:Integer=0;
|
|
_thr_atfork_list :atfork_head=(tqh_first:nil;tqh_last:@_thr_atfork_list.tqh_first);
|
|
_thr_atfork_lock :urwlock=(rw_state:0;rw_flags:0;
|
|
rw_blocked_readers:0;
|
|
rw_blocked_writers:0;
|
|
rw_spare:(0,0,0,0));
|
|
|
|
const
|
|
_thr_priorities :array[0..2] of pthread_prio=(
|
|
(pri_min:256;pri_max:767;pri_default:700), //FIFO
|
|
(pri_min:768;pri_max:959;pri_default:900), //OTHER
|
|
(pri_min:256;pri_max:767;pri_default:700) //RR
|
|
);
|
|
|
|
var
|
|
_pthread_attr_default :pthread_attr=(
|
|
sched_policy :SCHED_FIFO;
|
|
sched_inherit :PTHREAD_INHERIT_SCHED;
|
|
prio :700;
|
|
suspend :THR_CREATE_RUNNING;
|
|
flags :PTHREAD_SCOPE_SYSTEM;
|
|
_align :0;
|
|
stackaddr_attr:nil;
|
|
stacksize_attr:$10000;
|
|
guardsize_attr:0;
|
|
cpuset :0;
|
|
cpusetsize :0
|
|
);
|
|
|
|
_pthread_mutexattr_default:pthread_mutex_attr=(
|
|
m_type :PTHREAD_MUTEX_DEFAULT;
|
|
m_protocol:PTHREAD_PRIO_NONE;
|
|
m_ceiling :0
|
|
);
|
|
|
|
_pthread_mutexattr_adaptive_default:pthread_mutex_attr=(
|
|
m_type :PTHREAD_MUTEX_ADAPTIVE;
|
|
m_protocol:PTHREAD_PRIO_NONE;
|
|
m_ceiling :0
|
|
);
|
|
|
|
_pthread_condattr_default:pthread_cond_attr=(
|
|
c_pshared:PTHREAD_PROCESS_PRIVATE;
|
|
c_clockid:CLOCK_REALTIME;
|
|
);
|
|
|
|
_thr_pid:Integer;
|
|
|
|
_thr_is_smp :Integer=1; //kern.smp.cpus
|
|
_thr_guard_default :Integer;
|
|
_thr_stack_default :QWORD =THR_STACK_DEFAULT;
|
|
_thr_stack_initial :QWORD =THR_STACK_INITIAL;
|
|
_thr_page_size :Integer=4*1024; //getpagesize
|
|
|
|
_thr_spinloops :Integer;
|
|
_thr_yieldloops:Integer;
|
|
_gc_count :Integer;
|
|
|
|
_mutex_static_lock :umutex= (m_owner:0;m_flags:0;m_ceilings:(0,0);m_spare:(0,0));
|
|
_cond_static_lock :umutex= (m_owner:0;m_flags:0;m_ceilings:(0,0);m_spare:(0,0));
|
|
_rwlock_static_lock:umutex= (m_owner:0;m_flags:0;m_ceilings:(0,0);m_spare:(0,0));
|
|
_keytable_lock :umutex= (m_owner:0;m_flags:0;m_ceilings:(0,0);m_spare:(0,0));
|
|
_thr_list_lock :urwlock=(rw_state:0;rw_flags:0;
|
|
rw_blocked_readers:0;
|
|
rw_blocked_writers:0;
|
|
rw_spare:(0,0,0,0));
|
|
_thr_event_lock :umutex= (m_owner:0;m_flags:0;m_ceilings:(0,0);m_spare:(0,0));
|
|
|
|
init_once:Integer=0;
|
|
|
|
procedure _libpthread_init(curthread:p_pthread);
|
|
|
|
implementation
|
|
|
|
uses
|
|
sys_mmap;
|
|
|
|
const
|
|
g_user_stacksize=$10000;
|
|
|
|
procedure init_private;
|
|
begin
|
|
_thr_umutex_init(@_mutex_static_lock);
|
|
_thr_umutex_init(@_cond_static_lock);
|
|
_thr_umutex_init(@_rwlock_static_lock);
|
|
_thr_umutex_init(@_keytable_lock);
|
|
_thr_urwlock_init(@_thr_atfork_lock);
|
|
_thr_umutex_init(@_thr_event_lock);
|
|
//_thr_once_init();
|
|
//_thr_spinlock_init();
|
|
//_thr_list_init();
|
|
//_thr_wake_addr_init();
|
|
//_sleepq_init();
|
|
if (init_once=0) then
|
|
begin
|
|
//mib[0]:=1;
|
|
//mib[1]:=33;
|
|
//len:=8;
|
|
//ret:=sysctl(mib,2,@_usrstack,@len,nil,0);
|
|
//if (ret=-1) then
|
|
//begin
|
|
// Assert(false,'Cannot get kern.usrstack from sysctl');
|
|
//end;
|
|
//len:=4;
|
|
//sysctlbyname('kern.smp.cpus',@_thr_is_smp,@len,0,0);
|
|
//_thr_is_smp:=(1<_thr_is_smp);
|
|
//_thr_page_size:=getpagesize();
|
|
_pthread_attr_default.guardsize_attr:=_thr_page_size;
|
|
_thr_guard_default:=_pthread_attr_default.guardsize_attr;
|
|
//ret:=IsSystemProcess(getpid());
|
|
_thr_atfork_list.tqh_first:=nil;
|
|
_pthread_attr_default.stacksize_attr:=$200000;
|
|
//if (ret<>1) then
|
|
begin
|
|
_pthread_attr_default.stacksize_attr:=g_user_stacksize;
|
|
end;
|
|
end;
|
|
init_once:=1;
|
|
end;
|
|
|
|
procedure init_main_thread(thread:p_pthread);
|
|
var
|
|
ret:Pointer;
|
|
param:sched_param;
|
|
begin
|
|
thr_self(@thread^.tid);
|
|
|
|
thread^.attr:=_pthread_attr_default;
|
|
|
|
ret:=mmap(_usrstack-_thr_guard_default-_thr_stack_initial,_thr_guard_default,0,MAP_ANON,-1,0);
|
|
|
|
if (ret=MAP_FAILED) then
|
|
begin
|
|
Assert(false,'Cannot allocate red zone for initial thread');
|
|
Exit;
|
|
end;
|
|
thread^.attr.stackaddr_attr:=(_usrstack-_thr_stack_initial);
|
|
thread^.attr.stacksize_attr:=_thr_stack_initial;
|
|
thread^.attr.guardsize_attr:=_thr_guard_default;
|
|
thread^.attr.flags:=thread^.attr.flags or THR_STACK_USER;
|
|
|
|
thread^.magic:=THR_MAGIC;
|
|
|
|
thread^.cancel_enable:=1;
|
|
thread^.cancel_async:=0;
|
|
|
|
TAILQ_INIT(@thread^.mutexq);
|
|
TAILQ_INIT(@thread^.pp_mutexq);
|
|
|
|
thread^.state:=PS_RUNNING;
|
|
|
|
param:=Default(sched_param);
|
|
|
|
//_thr_getscheduler(thread^.tid,@thread^.attr.sched_policy,@param);
|
|
|
|
thread^.attr.prio:=param.sched_priority;
|
|
thread^.unwind_stackend:=_usrstack;
|
|
end;
|
|
|
|
procedure _libpthread_init(curthread:p_pthread);
|
|
var
|
|
first:Integer;
|
|
begin
|
|
if (_thr_initial<>nil) and (curthread=nil) then Exit;
|
|
|
|
_thr_pid:=getpid();
|
|
|
|
init_private;
|
|
|
|
first:=0;
|
|
|
|
if (curthread=nil) then
|
|
begin
|
|
//curthread:=_thr_alloc(nil);
|
|
if (curthread=nil) then
|
|
begin
|
|
Assert(false,'Can''t allocate initial thread');
|
|
end;
|
|
init_main_thread(curthread);
|
|
first:=1;
|
|
end;
|
|
|
|
THR_LIST_ADD(curthread);
|
|
_thread_active_threads:=1;
|
|
|
|
if (first<>0) then
|
|
begin
|
|
_thr_initial:=curthread;
|
|
_tcb_set(curthread^.tcb);
|
|
end;
|
|
end;
|
|
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|