mirror of
https://github.com/red-prig/fpPS4.git
synced 2025-02-21 14:51:07 +00:00
+
This commit is contained in:
parent
0888898ff6
commit
e714114c34
16
fpPS4.lpr
16
fpPS4.lpr
@ -162,6 +162,14 @@ begin
|
||||
Result:=3;
|
||||
end;
|
||||
|
||||
function ps4_sceHttp2Init(libnetMemId,libsslCtxId:Integer;
|
||||
poolSize:size_t;
|
||||
maxConcurrentRequest:Integer):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceHttp2Init:',poolSize);
|
||||
Result:=3;
|
||||
end;
|
||||
|
||||
function ps4_sceNpWebApiInitialize(libHttpCtxId:Integer;poolSize:size_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Writeln('sceNpWebApiInitialize:',libHttpCtxId,':',poolSize);
|
||||
@ -244,6 +252,11 @@ begin
|
||||
QWORD($85DA551140C55B7B):Result:=@ps4_sceSslInit;
|
||||
end;
|
||||
|
||||
'libSceHttp2':
|
||||
Case Info^.nid of
|
||||
QWORD($DC909EDE509B43C0):Result:=@ps4_sceHttp2Init;
|
||||
end;
|
||||
|
||||
'libSceNpWebApi':
|
||||
Case Info^.nid of
|
||||
QWORD($1B70272CD7510631):Result:=@ps4_sceNpWebApiInitialize;
|
||||
@ -574,6 +587,9 @@ begin
|
||||
//ps4_app.app_path:='G:\Games\Spelunky 2\CUSA20601\';
|
||||
//ps4_app.app_file:='G:\Games\Spelunky 2\CUSA20601\eboot.bin';
|
||||
|
||||
//ps4_app.app_path:='C:\Users\User\Desktop\Games\SPELUNKY2\CUSA20601\';
|
||||
//ps4_app.app_file:='C:\Users\User\Desktop\Games\SPELUNKY2\CUSA20601\eboot.bin';
|
||||
|
||||
//elf:=Telf_file(LoadPs4ElfFromFile('libSceLibcInternal.sprx'));
|
||||
//elf.Prepare;
|
||||
//elf.SavePs4ElfToFile('libSceLibcInternal.prx');
|
||||
|
215
ps4_libkernel/ps4_barrier.pas
Normal file
215
ps4_libkernel/ps4_barrier.pas
Normal file
@ -0,0 +1,215 @@
|
||||
unit ps4_barrier;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
windows,
|
||||
ps4_mutex,
|
||||
ps4_cond;
|
||||
|
||||
type
|
||||
p_pthread_barrierattr_t=^pthread_barrierattr_t;
|
||||
pthread_barrierattr_t=^pthread_barrier_attr;
|
||||
pthread_barrier_attr=record
|
||||
pshared:Integer;
|
||||
end;
|
||||
|
||||
p_pthread_barrier_t=^pthread_barrier_t;
|
||||
pthread_barrier_t=^pthread_barrier;
|
||||
pthread_barrier=record
|
||||
valid:DWORD;
|
||||
mlock:pthread_mutex;
|
||||
mcond:pthread_cond;
|
||||
cycle:Integer;
|
||||
count:Integer;
|
||||
waiters:Integer;
|
||||
refcount:Integer;
|
||||
destroying:Integer;
|
||||
end;
|
||||
|
||||
const
|
||||
PTHREAD_BARRIER_SERIAL_THREAD=-1;
|
||||
|
||||
function ps4_pthread_barrier_init(bar:p_pthread_barrier_t;attr:p_pthread_barrierattr_t;count:DWORD):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_barrier_destroy(bar:p_pthread_barrier_t):Integer; SysV_ABI_CDecl;
|
||||
function ps4_pthread_barrier_wait(bar:p_pthread_barrier_t):Integer; SysV_ABI_CDecl;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
atomic,
|
||||
sys_kernel,
|
||||
sys_signal;
|
||||
|
||||
const
|
||||
LIFE_BAR=$BAB1F00D;
|
||||
DEAD_BAR=$DEADBEEF;
|
||||
|
||||
function bar_init(m,mi:p_pthread_barrier_t;count:DWORD):Integer;
|
||||
var
|
||||
new:pthread_barrier_t;
|
||||
begin
|
||||
new:=AllocMem(SizeOf(pthread_barrier));
|
||||
if (new=nil) then Exit(ENOMEM);
|
||||
|
||||
new^.valid:=LIFE_BAR;
|
||||
new^.count:=count;
|
||||
|
||||
if (ps4_pthread_mutex_init(@new^.mlock,nil)<>0) then
|
||||
begin
|
||||
FreeMem(new);
|
||||
Exit(EAGAIN);
|
||||
end;
|
||||
|
||||
if (ps4_pthread_cond_init(@new^.mcond,nil)<>0) then
|
||||
begin
|
||||
FreeMem(new);
|
||||
Exit(EAGAIN);
|
||||
end;
|
||||
|
||||
if CAS(m^,mi^,new) then
|
||||
begin
|
||||
mi^:=new;
|
||||
end else
|
||||
begin
|
||||
FreeMem(new);
|
||||
mi^:=m^;
|
||||
end;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function _pthread_barrier_init(bar:p_pthread_barrier_t;attr:p_pthread_barrierattr_t;count:DWORD):Integer;
|
||||
var
|
||||
new:pthread_barrier_t;
|
||||
begin
|
||||
if (bar=nil) or (count=0) or (count>High(Integer)) then Exit(EINVAL);
|
||||
|
||||
if (attr<>nil) then
|
||||
if (attr^<>nil) then
|
||||
if (attr^^.pshared<>0) then //<>PTHREAD_PROCESS_PRIVATE
|
||||
begin
|
||||
Assert(false,'shared barrier not support!');
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
_sig_lock;
|
||||
Result:=bar_init(bar,@new,count);
|
||||
_sig_unlock;
|
||||
end;
|
||||
|
||||
function bar_enter(bar,bvp:p_pthread_barrier_t):Integer;
|
||||
var
|
||||
bv:pthread_barrier_t;
|
||||
begin
|
||||
if (bar=nil) then Exit(EINVAL);
|
||||
bv:=bar^;
|
||||
if (bv=nil) then Exit(EINVAL);
|
||||
if not safe_test(bv^.valid,LIFE_BAR) then Exit(ESRCH);
|
||||
|
||||
ps4_pthread_mutex_lock(@bv^.mlock);
|
||||
|
||||
bvp^:=bv;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function _pthread_barrier_destroy(bar:p_pthread_barrier_t):Integer;
|
||||
var
|
||||
bv:pthread_barrier_t;
|
||||
begin
|
||||
Result:=bar_enter(bar,@bv);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
if (bv^.destroying<>0) then //is destroying
|
||||
begin
|
||||
ps4_pthread_mutex_unlock(@bv^.mlock);
|
||||
Exit(EBUSY);
|
||||
end;
|
||||
|
||||
bv^.destroying:=1; //mark destroy
|
||||
repeat
|
||||
if (bv^.waiters>0) then
|
||||
begin
|
||||
bv^.destroying:=0; //unmark
|
||||
ps4_pthread_mutex_unlock(@bv^.mlock);
|
||||
Exit(EBUSY);
|
||||
end;
|
||||
if (bv^.refcount<>0) then
|
||||
begin
|
||||
ps4_pthread_cond_wait (@bv^.mcond,@bv^.mlock);
|
||||
ps4_pthread_mutex_lock(@bv^.mlock);
|
||||
end else
|
||||
begin
|
||||
Break;
|
||||
end;
|
||||
until false;
|
||||
|
||||
bar^:=nil;
|
||||
bv^.valid:=DEAD_BAR; //mark free
|
||||
bv^.destroying:=0; //unmark
|
||||
|
||||
ps4_pthread_mutex_unlock(@bv^.mlock);
|
||||
|
||||
ps4_pthread_mutex_destroy(@bv^.mlock);
|
||||
ps4_pthread_cond_destroy (@bv^.mcond);
|
||||
|
||||
SwFreeMem(bv);
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function _pthread_barrier_wait(bar:p_pthread_barrier_t):Integer;
|
||||
var
|
||||
bv:pthread_barrier_t;
|
||||
cycle:Integer;
|
||||
begin
|
||||
Result:=bar_enter(bar,@bv);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
if (System.InterlockedIncrement(bv^.waiters)=bv^.count) then
|
||||
begin
|
||||
// Current thread is lastest thread
|
||||
bv^.waiters:=0;
|
||||
System.InterlockedIncrement(bv^.cycle);
|
||||
ps4_pthread_cond_broadcast(@bv^.mcond);
|
||||
ps4_pthread_mutex_unlock (@bv^.mlock);
|
||||
Result:=PTHREAD_BARRIER_SERIAL_THREAD;
|
||||
end else
|
||||
begin
|
||||
cycle:=bv^.cycle;
|
||||
System.InterlockedIncrement(bv^.refcount);
|
||||
|
||||
repeat
|
||||
ps4_pthread_cond_wait (@bv^.mcond,@bv^.mlock);
|
||||
ps4_pthread_mutex_lock(@bv^.mlock);
|
||||
// test cycle to avoid bogus wakeup
|
||||
until (cycle<>bv^.cycle);
|
||||
|
||||
if (System.InterlockedDecrement(bv^.refcount)=0) and (bv^.destroying<>0) then
|
||||
begin
|
||||
ps4_pthread_cond_broadcast(@bv^.mcond);
|
||||
end;
|
||||
|
||||
ps4_pthread_mutex_unlock(@bv^.mlock);
|
||||
Result:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ps4_pthread_barrier_init(bar:p_pthread_barrier_t;attr:p_pthread_barrierattr_t;count:DWORD):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_pthread_barrier_init(bar,attr,count);
|
||||
end;
|
||||
|
||||
function ps4_pthread_barrier_destroy(bar:p_pthread_barrier_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_pthread_barrier_destroy(bar);
|
||||
end;
|
||||
|
||||
function ps4_pthread_barrier_wait(bar:p_pthread_barrier_t):Integer; SysV_ABI_CDecl;
|
||||
begin
|
||||
Result:=_pthread_barrier_wait(bar);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -21,7 +21,7 @@ type
|
||||
|
||||
p_pthread_cond=^pthread_cond;
|
||||
pthread_cond=^pthread_cond_t;
|
||||
pthread_cond_t=record
|
||||
pthread_cond_t=packed record
|
||||
valid:DWORD;
|
||||
busy :DWORD;
|
||||
waiters_count_:DWORD;
|
||||
|
@ -30,7 +30,7 @@ type
|
||||
end;
|
||||
|
||||
pwef_node=^wef_node;
|
||||
wef_node=record
|
||||
wef_node=packed record
|
||||
pNext,pPrev:pwef_node;
|
||||
//
|
||||
thread:THandle;
|
||||
|
@ -15,6 +15,7 @@ uses
|
||||
ps4_cond,
|
||||
ps4_sema,
|
||||
ps4_rwlock,
|
||||
ps4_barrier,
|
||||
ps4_time,
|
||||
ps4_kernel_file,
|
||||
ps4_queue,
|
||||
@ -858,6 +859,14 @@ begin
|
||||
|
||||
//cond
|
||||
|
||||
//barrier
|
||||
|
||||
lib^.set_proc($66C5CB16D7768EA4,@ps4_pthread_barrier_init);
|
||||
lib^.set_proc($F8FAAE6FD1D908FA,@ps4_pthread_barrier_destroy);
|
||||
lib^.set_proc($09AC1980262A5D69,@ps4_pthread_barrier_wait);
|
||||
|
||||
//barrier
|
||||
|
||||
//thread
|
||||
|
||||
lib^.set_proc($9EC628351CB0C0D8,@ps4_scePthreadAttrInit);
|
||||
|
@ -19,7 +19,7 @@ const
|
||||
|
||||
type
|
||||
pwsem_node=^wsem_node;
|
||||
wsem_node=record
|
||||
wsem_node=packed record
|
||||
pNext,pPrev:pwsem_node;
|
||||
//
|
||||
thread:THandle;
|
||||
@ -40,7 +40,7 @@ type
|
||||
|
||||
PSceKernelSema=^SceKernelSema;
|
||||
SceKernelSema=^_sem_t;
|
||||
_sem_t=record
|
||||
_sem_t=packed record
|
||||
valid:DWORD;
|
||||
init :Integer;
|
||||
max :Integer;
|
||||
|
Loading…
x
Reference in New Issue
Block a user