Skip to content

Commit

Permalink
scePthreadKeyCreate and etc
Browse files Browse the repository at this point in the history
  • Loading branch information
red-prig committed Dec 9, 2022
1 parent 703d942 commit 56f0d24
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 157 deletions.
12 changes: 11 additions & 1 deletion kernel/ps4_libkernel.pas
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface
ps4_map_mm,
ps4_mspace,
ps4_pthread,
ps4_pthread_key,
ps4_signal,
ps4_mutex,
ps4_cond,
Expand Down Expand Up @@ -1058,12 +1059,21 @@ function Load_libkernel(Const name:RawByteString):TElf_node;
lib^.set_proc($D71BED515C75FD28,@ps4___pthread_cleanup_push_imp);
lib^.set_proc($896B0595831FDCAC,@ps4___pthread_cleanup_pop_imp);

//thread

//pthread_key

lib^.set_proc($9AA50B35D8A64E7D,@ps4_pthread_key_create);
lib^.set_proc($E81A4466E0D3ED82,@ps4_pthread_key_delete);
lib^.set_proc($D3F297692EF4C72E,@ps4_pthread_getspecific);
lib^.set_proc($5AB38BBC7534C903,@ps4_pthread_setspecific);

//thread
lib^.set_proc($81E0DAAA01FD9538,@ps4_scePthreadKeyCreate);
lib^.set_proc($3EB747BAE0DE9216,@ps4_scePthreadKeyDelete);
lib^.set_proc($7A886DEE640E0A6A,@ps4_scePthreadGetspecific);
lib^.set_proc($F81CD7624A9878B1,@ps4_scePthreadSetspecific);

//pthread_key

lib^.set_proc($5AC95C2B51507062,@ps4_sceKernelIsNeoMode);
lib^.set_proc($9A9C4076A5BB74A6,@ps4_sceKernelIsProspero);
Expand Down
157 changes: 2 additions & 155 deletions kernel/ps4_pthread.pas
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
interface

uses
LFQueue,
windows,
sys_crt,
sys_pthread,
Expand Down Expand Up @@ -92,11 +91,6 @@ procedure ps4___pthread_cleanup_push_imp(routine:t_cb_proc;
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;
function ps4_pthread_key_delete(Key:pthread_key_t):Integer; SysV_ABI_CDecl;
function ps4_pthread_getspecific(Key:pthread_key_t):Pointer; SysV_ABI_CDecl;
function ps4_pthread_setspecific(Key:pthread_key_t;value:Pointer):Integer; SysV_ABI_CDecl;

function _pthread_run_entry(pthread:p_pthread;name:Pchar;stack:PDWORD):Integer;

implementation
Expand All @@ -105,26 +99,12 @@ implementation
atomic,
spinlock,
sys_kernel,
ps4_pthread_key,
ps4_mutex,
ps4_map_mm,
ps4_program,
ps4_elf;

type
p_pthread_key_node=^_pthread_key_node;
_pthread_key_node=packed record
next_:p_pthread_key_node;
version_:ptruint;
dest_:t_cb_proc;
end;

var
_pthread_key_nodes:array[0..SCE_PTHREAD_KEYS_MAX-1] of _pthread_key_node;
_pthread_key_queue:TIntrusiveMPSCQueue;
_pthread_key_queue_lock:Pointer;

procedure _pthread_keys_cleanup_dest; forward;

//struct dl_phdr_info
procedure ps4_pthread_cxa_finalize(P:Pointer); SysV_ABI_CDecl;
begin
Expand Down Expand Up @@ -391,7 +371,7 @@ procedure _thread_cleanup;
end;

_sig_lock;
_pthread_keys_cleanup_dest;
_thread_cleanupspecific;
ps4_app.FreeThread;
UnRegistredStack;
_sig_unlock;
Expand Down Expand Up @@ -1023,139 +1003,6 @@ procedure ps4___pthread_cleanup_pop_imp(execute:Integer); SysV_ABI_CDecl;
end;
end;

procedure _pthread_keys_init;
var
i:Integer;
begin
_pthread_key_queue.Create;
For i:=Low(_pthread_key_nodes) to High(_pthread_key_nodes) do
begin
_pthread_key_nodes[i]:=Default(_pthread_key_node);
_pthread_key_queue.Push(@_pthread_key_nodes[i]);
end;
end;

procedure _pthread_keys_cleanup_dest;
var
i:Integer;
local:p_pthread_key_data;

node:p_pthread_key_node;
version:ptruint;
dest:t_cb_proc;
begin
local:=@tcb_thread^.keys[0];

For i:=Low(_pthread_key_nodes) to High(_pthread_key_nodes) do
begin
node:=@_pthread_key_nodes[i];

version:=load_consume(node^.version_);
dest:=t_cb_proc(load_consume(Pointer(node^.dest_)));

if (ptruint(dest)>1) and
(local[i].version_=version) and
(local[i].data_<>nil) then
begin
dest(local[i].data_);
end;

end;

end;

function ps4_pthread_key_create(pKey:Ppthread_key_t;dest:t_cb_proc):Integer; SysV_ABI_CDecl;
var
node:p_pthread_key_node;
Key:pthread_key_t;
begin
if (pKey=nil) then Exit(EINVAL);
Writeln('pthread_key_create',' ',ps4_pthread_self^.sig._lock);

if (dest=nil) then dest:=t_cb_proc(1);

node:=nil;
spin_lock(_pthread_key_queue_lock);
_pthread_key_queue.Pop(node);
spin_unlock(_pthread_key_queue_lock);

if (node=nil) then Exit(EAGAIN);

System.InterlockedIncrement(Pointer(node^.version_));
XCHG(Pointer(node^.dest_),Pointer(dest));

Key:=(node-p_pthread_key_node(@_pthread_key_nodes));
Key:=Key+1;

pKey^:=Key;
Result:=0;
end;

function ps4_pthread_key_delete(Key:pthread_key_t):Integer; SysV_ABI_CDecl;
var
node:p_pthread_key_node;
begin
Key:=Key-1;

if (DWORD(Key)>SCE_PTHREAD_KEYS_MAX) then Exit(EINVAL);
Writeln('pthread_key_delete');

node:=@_pthread_key_nodes[Key];

if (XCHG(Pointer(node^.dest_),nil)=nil) then Exit(EINVAL);

System.InterlockedIncrement(Pointer(node^.version_));

_pthread_key_queue.Push(node);
end;

function ps4_pthread_getspecific(Key:pthread_key_t):Pointer; SysV_ABI_CDecl;
var
node:p_pthread_key_node;
version:ptruint;
local:p_pthread_key_data;
begin
Key:=Key-1;

if (DWORD(Key)>=SCE_PTHREAD_KEYS_MAX) then Exit(nil);

node:=@_pthread_key_nodes[Key];

version:=load_consume(node^.version_);
if (load_consume(Pointer(node^.dest_))=nil) then Exit(nil);

local:=@tcb_thread^.keys[Key];

if (local^.version_<>version) then Exit(nil);

Result:=local^.data_;
end;

function ps4_pthread_setspecific(Key:pthread_key_t;value:Pointer):Integer; SysV_ABI_CDecl;
var
node:p_pthread_key_node;
version:ptruint;
local:p_pthread_key_data;
begin
Key:=Key-1;

if (DWORD(Key)>=SCE_PTHREAD_KEYS_MAX) then Exit(EINVAL);

node:=@_pthread_key_nodes[Key];

version:=load_consume(node^.version_);
if (load_consume(Pointer(node^.dest_))=nil) then Exit(EINVAL);

local:=@tcb_thread^.keys[Key];

local^.version_:=version;
local^.data_ :=value;

Result:=0;
end;

initialization
_pthread_keys_init;

end.

Expand Down
Loading

0 comments on commit 56f0d24

Please sign in to comment.