From ba241c4fc455d00b533ef4fccc9f29c8799c076c Mon Sep 17 00:00:00 2001 From: red-prig Date: Mon, 12 Sep 2022 22:37:16 +0300 Subject: [PATCH] + --- kernel/ps4_libkernel.pas | 3 +- kernel/ps4_pthread.pas | 81 +++++++++++++++++++++++++++++++++++----- ps4_elf.pas | 17 ++++----- ps4_program.pas | 4 +- sys/sys_pthread.pas | 30 +++++++++------ 5 files changed, 102 insertions(+), 33 deletions(-) diff --git a/kernel/ps4_libkernel.pas b/kernel/ps4_libkernel.pas index 39868d1f..0702b48f 100644 --- a/kernel/ps4_libkernel.pas +++ b/kernel/ps4_libkernel.pas @@ -182,6 +182,7 @@ end; //cb used in pthread_exit function ps4_sceKernelSetThreadDtors(Proc:TProcedure):Integer; SysV_ABI_CDecl; begin + sceKernelThreadDtors:=Proc; Writeln('sceKernelSetThreadDtors:',HexStr(proc)); Result:=0; end; @@ -309,7 +310,7 @@ begin ps4_app.InitCode; - i:=node.module_start(argc,argp); + i:=node.module_start(argc,argp,nil); Result:=node.Handle; node.Release; diff --git a/kernel/ps4_pthread.pas b/kernel/ps4_pthread.pas index 68e8f9ac..919eaada 100644 --- a/kernel/ps4_pthread.pas +++ b/kernel/ps4_pthread.pas @@ -79,9 +79,9 @@ procedure ps4_pthread_yield(); SysV_ABI_CDecl; procedure ps4_pthread_cleanup_push(routine:t_cb_proc;arg:Pointer); SysV_ABI_CDecl; procedure ps4_pthread_cleanup_pop(execute:Integer); SysV_ABI_CDecl; -procedure ps4___pthread_cleanup_push_imp(cleanup_routine:t_cb_proc; - cleanup_arg:Pointer; - cleanup_info:p_pthread_cleanup_info); SysV_ABI_CDecl; +procedure ps4___pthread_cleanup_push_imp(routine:t_cb_proc; + arg:Pointer; + info:p_pthread_cleanup); SysV_ABI_CDecl; procedure ps4___pthread_cleanup_pop_imp(execute:Integer); SysV_ABI_CDecl; function ps4_pthread_key_create(pKey:Ppthread_key_t;dest:t_cb_proc):Integer; SysV_ABI_CDecl; @@ -363,8 +363,25 @@ begin _sig_unlock; end; +procedure _pthread_cleanup_pop; inline; +var + curthread:pthread; +begin + curthread:=_get_curthread; + if (curthread=nil) then Exit; + + While (curthread^.cleanup<>nil) do ps4___pthread_cleanup_pop_imp(1); +end; + procedure _thread_cleanup; begin + _pthread_cleanup_pop; + + if (sceKernelThreadDtors<>nil) then + begin + sceKernelThreadDtors(); + end; + _sig_lock; _pthread_keys_cleanup_dest; ps4_app.FreeThread; @@ -863,27 +880,73 @@ begin end; procedure ps4_pthread_cleanup_push(routine:t_cb_proc;arg:Pointer); SysV_ABI_CDecl; +var + curthread:pthread; + newbuf:p_pthread_cleanup; begin Writeln('pthread_cleanup_push'); + + curthread:=_get_curthread; + if (curthread=nil) then Exit; + + newbuf:=AllocMem(SizeOf(pthread_cleanup)); + if (newbuf=nil) then Exit; + + newbuf^.routine :=routine; + newbuf^.routine_arg:=arg; + newbuf^.onheap :=1; + newbuf^.prev :=curthread^.cleanup; + + curthread^.cleanup:=newbuf; end; procedure ps4_pthread_cleanup_pop(execute:Integer); SysV_ABI_CDecl; begin - Assert(execute=0); - Writeln('pthread_cleanup_pop'); + ps4___pthread_cleanup_pop_imp(execute); end; -procedure ps4___pthread_cleanup_push_imp(cleanup_routine:t_cb_proc; - cleanup_arg:Pointer; - cleanup_info:p_pthread_cleanup_info); SysV_ABI_CDecl; +procedure ps4___pthread_cleanup_push_imp(routine:t_cb_proc; + arg:Pointer; + info:p_pthread_cleanup); SysV_ABI_CDecl; +var + curthread:pthread; begin Writeln('__pthread_cleanup_push_imp'); + + curthread:=_get_curthread; + if (curthread=nil) then Exit; + + info^.routine :=routine; + info^.routine_arg:=arg; + info^.onheap :=0; + info^.prev :=curthread^.cleanup; + + curthread^.cleanup:=info; end; procedure ps4___pthread_cleanup_pop_imp(execute:Integer); SysV_ABI_CDecl; +var + curthread:pthread; + old:p_pthread_cleanup; begin - Assert(execute=0); Writeln('__pthread_cleanup_pop_imp'); + + curthread:=_get_curthread; + if (curthread=nil) then Exit; + + old:=curthread^.cleanup; + if (old<>nil) then + begin + curthread^.cleanup:=old^.prev; + if (execute<>0) then + begin + old^.routine(old^.routine_arg); + end; + if (old^.onheap<>0) then + begin + FreeMem(old); + end; + end; end; procedure _pthread_keys_init; diff --git a/ps4_elf.pas b/ps4_elf.pas index 049d01cb..1ece1bdf 100644 --- a/ps4_elf.pas +++ b/ps4_elf.pas @@ -243,7 +243,7 @@ type procedure InitThread(is_static:QWORD); override; Procedure InitProt; override; Procedure InitCode; override; - function module_start(argc:size_t;argp:PPointer):Integer; override; + function module_start(argc:size_t;argp,param:PPointer):Integer; override; function GetCodeFrame:TMemChunk; override; function GetEntryPoint:Pointer; override; Function GetModuleInfo:TKernelModuleInfo; override; @@ -2556,7 +2556,7 @@ begin if (Prog<>Self) then begin - module_start(0,nil); + module_start(0,nil,nil); end; //if (Prog<>Self) then @@ -2613,25 +2613,22 @@ begin FInitCode:=True; end; -function Telf_file.module_start(argc:size_t;argp:PPointer):Integer; +function Telf_file.module_start(argc:size_t;argp,param:PPointer):Integer; var - mp:PsceModuleParam; - M:Pointer; + //mp:PsceModuleParam; + //M:Pointer; P:TmoduleStart; begin Result:=0; - Pointer(mp):=Pointer(mMap.pAddr+pModuleParam); - + //Pointer(mp):=Pointer(mMap.pAddr+pModuleParam); //M:=get_proc_by_name('module_start'); - M:=nil; Pointer(P):=Pointer(mMap.pAddr+dtInit); Writeln('module_start'); - Result:=P(argc,argp,M); - + Result:=P(argc,argp,param); end; function Telf_file.GetCodeFrame:TMemChunk; diff --git a/ps4_program.pas b/ps4_program.pas index 135299f3..37551b93 100644 --- a/ps4_program.pas +++ b/ps4_program.pas @@ -86,7 +86,7 @@ type Procedure FreeThread; virtual; Procedure InitProt; virtual; Procedure InitCode; virtual; - function module_start(argc:size_t;argp:PPointer):Integer; virtual; + function module_start(argc:size_t;argp,param:PPointer):Integer; virtual; function GetCodeFrame:TMemChunk; virtual; function GetEntryPoint:Pointer; virtual; Function GetModuleInfo:TKernelModuleInfo; virtual; @@ -901,7 +901,7 @@ begin FInitCode:=True; end; -function TElf_node.module_start(argc:size_t;argp:PPointer):Integer; +function TElf_node.module_start(argc:size_t;argp,param:PPointer):Integer; begin Result:=0; end; diff --git a/sys/sys_pthread.pas b/sys/sys_pthread.pas index 0d60dd16..30171367 100644 --- a/sys/sys_pthread.pas +++ b/sys/sys_pthread.pas @@ -115,6 +115,20 @@ type data_:Pointer; end; + t_init_routine_proc=procedure; SysV_ABI_CDecl; + t_cb_proc=procedure(data:Pointer); SysV_ABI_CDecl; + + Ppthread_key_t=^pthread_key_t; + pthread_key_t=DWORD; + + p_pthread_cleanup=^pthread_cleanup; + pthread_cleanup=packed record + prev:p_pthread_cleanup; + routine:t_cb_proc; + routine_arg:Pointer; + onheap:Integer; + end; + p_pthread=^pthread; pthread=^pthread_t; pthread_t=record @@ -128,22 +142,13 @@ type // errno:QWORD; // + cleanup:p_pthread_cleanup; + // keys:array[0..SCE_PTHREAD_KEYS_MAX-1] of _pthread_key_data; // sig:sigqueue_t; end; - t_init_routine_proc=procedure; SysV_ABI_CDecl; - t_cb_proc=procedure(data:Pointer); SysV_ABI_CDecl; - - Ppthread_key_t=^pthread_key_t; - pthread_key_t=DWORD; - - p_pthread_cleanup_info=^_pthread_cleanup_info; - _pthread_cleanup_info=packed record - pthread_cleanup_pad:array[0..7] of qword; - end; - PSceKernelSchedParam=^SceKernelSchedParam; SceKernelSchedParam=packed record sched_priority:Integer; @@ -152,6 +157,9 @@ type threadvar tcb_thread:pthread; +var + sceKernelThreadDtors:TProcedure; + function _get_curthread:pthread; inline; function sysv_wrapper(arg,proc:Pointer):Pointer; SysV_ABI_CDecl;