mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
b88b495ea4
commit
fb47665e31
|
@ -29,7 +29,7 @@ type
|
|||
|
||||
p_urwlock=^urwlock;
|
||||
urwlock=packed record
|
||||
rw_state :Integer;
|
||||
rw_state :DWORD;
|
||||
rw_flags :DWORD;
|
||||
rw_blocked_readers:DWORD;
|
||||
rw_blocked_writers:DWORD;
|
||||
|
|
|
@ -1398,12 +1398,10 @@ begin
|
|||
until false;
|
||||
|
||||
umtxq_lock(uq^.uq_key);
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
umtxq_signal(uq^.uq_key,High(Integer));
|
||||
end;
|
||||
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
|
||||
umtx_key_release(uq^.uq_key);
|
||||
|
@ -1585,6 +1583,7 @@ begin
|
|||
|
||||
if ((uq^.uq_flags and UQF_UMTXQ)=0) then
|
||||
begin
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
|
@ -1592,12 +1591,14 @@ begin
|
|||
begin
|
||||
oldlen:=uq^.uq_cur_queue^.length;
|
||||
umtxq_remove(uq);
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
if (oldlen=1) then
|
||||
begin
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
suword32(cv^.c_has_waiters,0);
|
||||
umtxq_lock(uq^.uq_key);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
end;
|
||||
if (Result=ERESTART) then
|
||||
begin
|
||||
|
@ -1605,8 +1606,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
|
||||
_exit:
|
||||
umtx_key_release(uq^.uq_key);
|
||||
end;
|
||||
|
@ -1623,21 +1622,17 @@ begin
|
|||
if (key=nil) then Exit(EFAULT);
|
||||
|
||||
umtxq_lock(key);
|
||||
|
||||
count:=umtxq_count(key);
|
||||
nwake:=umtxq_signal(key,1);
|
||||
if (count<=nwake) then
|
||||
begin
|
||||
umtxq_unlock(&key);
|
||||
Result:=suword32(cv^.c_has_waiters,0);
|
||||
umtxq_lock(&key);
|
||||
end;
|
||||
|
||||
umtxq_unlock(key);
|
||||
|
||||
umtx_key_release(key);
|
||||
if (count<=nwake) then
|
||||
begin
|
||||
Result:=suword32(cv^.c_has_waiters,0);
|
||||
if (Result<>0) then Result:=EFAULT;
|
||||
end;
|
||||
|
||||
if (Result<>0) then Result:=EFAULT;
|
||||
umtx_key_release(key);
|
||||
end;
|
||||
|
||||
function do_cv_broadcast(td:p_kthread;cv:p_ucond):Integer;
|
||||
|
@ -1655,10 +1650,9 @@ begin
|
|||
umtxq_unlock(key);
|
||||
|
||||
Result:=suword32(cv^.c_has_waiters,0);
|
||||
if (Result<>0) then Result:=EFAULT;
|
||||
|
||||
umtx_key_release(key);
|
||||
|
||||
if (Result<>0) then Result:=EFAULT;
|
||||
end;
|
||||
|
||||
////
|
||||
|
@ -1795,7 +1789,7 @@ end;
|
|||
|
||||
function do_rw_rdlock2(td:p_kthread;rwlock:p_urwlock;fflag:QWORD;timeout:ptimespec):Integer;
|
||||
var
|
||||
ts,ts2,ts3,tv:Int64;
|
||||
ts,ts2,tv:Int64;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
|
@ -1816,9 +1810,7 @@ begin
|
|||
Break;
|
||||
end;
|
||||
|
||||
ts3:=ts;
|
||||
ts3:=ts3-ts2;
|
||||
tv:=ts3;
|
||||
tv:=ts-ts2;
|
||||
until false;
|
||||
|
||||
if (Result=ERESTART) then
|
||||
|
@ -1927,7 +1919,7 @@ begin
|
|||
state:=fuword32(rwlock^.rw_state);
|
||||
end;
|
||||
|
||||
blocked_writers:=fuword32(&rwlock^.rw_blocked_writers);
|
||||
blocked_writers:=fuword32(rwlock^.rw_blocked_writers);
|
||||
suword32(rwlock^.rw_blocked_writers,blocked_writers-1);
|
||||
|
||||
if (blocked_writers=1) then
|
||||
|
@ -1964,7 +1956,7 @@ end;
|
|||
|
||||
function do_rw_wrlock2(td:p_kthread;rwlock:p_urwlock;fflag:QWORD;timeout:ptimespec):Integer;
|
||||
var
|
||||
ts,ts2,ts3,tv:Int64;
|
||||
ts,ts2,tv:Int64;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
|
@ -1985,9 +1977,7 @@ begin
|
|||
Break;
|
||||
end;
|
||||
|
||||
ts3:=ts;
|
||||
ts3:=ts3-ts2;
|
||||
tv:=ts3;
|
||||
tv:=ts-ts2;
|
||||
until false;
|
||||
|
||||
if (Result=ERESTART) then
|
||||
|
@ -1996,7 +1986,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
|
||||
function do_rw_unlock(td:p_kthread;rwlock:p_urwlock):Integer;
|
||||
label
|
||||
_exit;
|
||||
|
@ -2114,6 +2103,108 @@ end;
|
|||
|
||||
////
|
||||
|
||||
function do_sem_wait(td:p_kthread;sem:p__usem;timeout:ptimespec):Integer;
|
||||
var
|
||||
uq:p_umtx_q;
|
||||
count:DWORD;
|
||||
cts,ets,tv:Int64;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
uq:=td^.td_umtxq;
|
||||
|
||||
uq^.uq_key:=umtx_key_get(sem,TYPE_SEM);
|
||||
if (uq^.uq_key=nil) then Exit(EFAULT);
|
||||
|
||||
umtxq_lock(uq^.uq_key);
|
||||
umtxq_insert(uq);
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
|
||||
if ((fuword32(sem^._has_waiters))=0) then
|
||||
begin
|
||||
casuword32(sem^._has_waiters,0,1);
|
||||
end;
|
||||
|
||||
count:=fuword32(sem^._count);
|
||||
|
||||
if (count<>0) then
|
||||
begin
|
||||
umtxq_lock(uq^.uq_key);
|
||||
umtxq_remove(uq);
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
umtx_key_release(uq^.uq_key);
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
if (timeout=nil) then
|
||||
begin
|
||||
Result:=umtxq_sleep(uq,NT_INFINITE);
|
||||
end else
|
||||
begin
|
||||
ets:=get_unit_uptime;
|
||||
tv:=TIMESPEC_TO_UNIT(timeout);
|
||||
ets:=ets+tv;
|
||||
|
||||
repeat
|
||||
Result:=umtxq_sleep(uq,-tv);
|
||||
if (Result<>ETIMEDOUT) then Break;
|
||||
|
||||
cts:=get_unit_uptime;
|
||||
|
||||
if (cts>=ets) then
|
||||
begin
|
||||
Result:=ETIMEDOUT;
|
||||
Break;
|
||||
end;
|
||||
|
||||
tv:=ets-cts;
|
||||
until false;
|
||||
end;
|
||||
|
||||
if ((uq^.uq_flags and UQF_UMTXQ)=0) then
|
||||
begin
|
||||
Result:=0;
|
||||
end else
|
||||
begin
|
||||
umtxq_lock(uq^.uq_key);
|
||||
umtxq_remove(uq);
|
||||
umtxq_unlock(uq^.uq_key);
|
||||
|
||||
if (Result=ERESTART) and (timeout<>nil) then
|
||||
begin
|
||||
Result:=EINTR;
|
||||
end;
|
||||
end;
|
||||
|
||||
umtx_key_release(uq^.uq_key);
|
||||
end;
|
||||
|
||||
function do_sem_wake(td:p_kthread;sem:p__usem):Integer;
|
||||
var
|
||||
key:umtx_key;
|
||||
count,nwake:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
key:=umtx_key_get(sem,TYPE_SEM);
|
||||
if (key=nil) then Exit(EFAULT);
|
||||
|
||||
umtxq_lock(key);
|
||||
count:=umtxq_count(key);
|
||||
nwake:=umtxq_signal(key,1);
|
||||
umtxq_unlock(key);
|
||||
|
||||
if (count<=nwake) then
|
||||
begin
|
||||
Result:=suword32(sem^._has_waiters,0);
|
||||
if (Result<>0) then Result:=EFAULT;
|
||||
end;
|
||||
|
||||
umtx_key_release(key);
|
||||
end;
|
||||
|
||||
////
|
||||
|
||||
function umtx_copyin_timeout(addr:Pointer;tsp:ptimespec):Integer;
|
||||
begin
|
||||
Result:=copyin(addr,tsp,SizeOf(timespec));
|
||||
|
@ -2382,6 +2473,28 @@ begin
|
|||
Result:=do_unlock_umtx(td,mtx,td^.td_tid);
|
||||
end;
|
||||
|
||||
function __umtx_op_sem_wait(td:p_kthread;obj:Pointer;val:QWORD;uaddr1,uaddr2:Pointer):Integer;
|
||||
var
|
||||
ts:ptimespec;
|
||||
timeout:timespec;
|
||||
begin
|
||||
if (ptrint(obj)<$1000) then Exit(EFAULT);
|
||||
|
||||
ts:=nil;
|
||||
if (uaddr2<>nil) then
|
||||
begin
|
||||
Result:=umtx_copyin_timeout(uaddr2,@timeout);
|
||||
if (Result<>0) then Exit;
|
||||
ts:=@timeout;
|
||||
end;
|
||||
Result:=do_sem_wait(td,obj,ts);
|
||||
end;
|
||||
|
||||
function __umtx_op_sem_wake(td:p_kthread;obj:Pointer;val:QWORD;uaddr1,uaddr2:Pointer):Integer; inline;
|
||||
begin
|
||||
Result:=do_sem_wake(td,obj)
|
||||
end;
|
||||
|
||||
function _sys_umtx_op(obj:Pointer;op:Integer;val:QWORD;uaddr1,uaddr2:Pointer):Integer;
|
||||
var
|
||||
td:p_kthread;
|
||||
|
@ -2409,8 +2522,8 @@ begin
|
|||
UMTX_OP_WAKE_PRIVATE :Result:=__umtx_op_wake_private (td,obj,val,uaddr1,uaddr2);
|
||||
UMTX_OP_MUTEX_WAIT :Result:=__umtx_op_wait_umutex (td,obj,val,uaddr1,uaddr2);
|
||||
UMTX_OP_MUTEX_WAKE :Result:=__umtx_op_wake_umutex (td,obj,val,uaddr1,uaddr2);
|
||||
//UMTX_OP_SEM_WAIT
|
||||
//UMTX_OP_SEM_WAKE
|
||||
UMTX_OP_SEM_WAIT :Result:=__umtx_op_sem_wait (td,obj,val,uaddr1,uaddr2);
|
||||
UMTX_OP_SEM_WAKE :Result:=__umtx_op_sem_wake (td,obj,val,uaddr1,uaddr2);
|
||||
UMTX_OP_NWAKE_PRIVATE :Result:=__umtx_op_nwake_private (td,obj,val,uaddr1,uaddr2);
|
||||
UMTX_OP_MUTEX_WAKE2 :Result:=__umtx_op_wake2_umutex (td,obj,val,uaddr1,uaddr2);
|
||||
else
|
||||
|
|
|
@ -12,10 +12,8 @@ function copyin(udaddr,kaddr:Pointer;len:ptruint):Integer; inline;
|
|||
function copyinstr(udaddr,kaddr:Pointer;len:ptruint;lencopied:pptruint):Integer;
|
||||
function copyout(udaddr,kaddr:Pointer;len:ptruint):Integer; inline;
|
||||
function fuword32(var base:DWORD):DWORD; inline;
|
||||
function fuword32(var base:Integer):Integer; inline;
|
||||
function fuword64(var base:QWORD):QWORD; inline;
|
||||
function casuword32(var base:DWORD;oldval,newval:DWORD):DWORD; inline;
|
||||
function casuword32(var base:Integer;oldval,newval:Integer):Integer; inline;
|
||||
function casuword64(var base:QWORD;oldval,newval:QWORD):QWORD; inline;
|
||||
function suword32(var base:DWORD;word:DWORD):DWORD; inline;
|
||||
|
||||
|
@ -74,14 +72,6 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function fuword32(var base:Integer):Integer; inline;
|
||||
begin
|
||||
if (NtReadVirtualMemory(NtCurrentProcess,@base,@Result,SizeOf(DWORD),nil)<>0) then
|
||||
begin
|
||||
Result:=-1;
|
||||
end;
|
||||
end;
|
||||
|
||||
function fuword64(var base:QWORD):QWORD; inline;
|
||||
begin
|
||||
if (NtReadVirtualMemory(NtCurrentProcess,@base,@Result,SizeOf(QWORD),nil)<>0) then
|
||||
|
@ -95,11 +85,6 @@ begin
|
|||
Result:=System.InterlockedCompareExchange(base,newval,oldval);
|
||||
end;
|
||||
|
||||
function casuword32(var base:Integer;oldval,newval:Integer):Integer; inline;
|
||||
begin
|
||||
Result:=System.InterlockedCompareExchange(base,newval,oldval);
|
||||
end;
|
||||
|
||||
function casuword64(var base:QWORD;oldval,newval:QWORD):QWORD; inline;
|
||||
begin
|
||||
Result:=System.InterlockedCompareExchange64(base,newval,oldval);
|
||||
|
|
|
@ -20,6 +20,7 @@ uses
|
|||
|
||||
var
|
||||
mtx:umutex;
|
||||
rwl:urwlock;
|
||||
e:Integer;
|
||||
|
||||
event:Thandle;
|
||||
|
@ -45,7 +46,8 @@ begin
|
|||
repeat
|
||||
|
||||
//e:=sys_umtx_op(@mtx,{UMTX_OP_MUTEX_LOCK} UMTX_OP_LOCK,td.td_tid,nil,nil);
|
||||
e:=sys_umtx_op(@mtx,UMTX_OP_MUTEX_LOCK,td.td_tid,nil,nil);
|
||||
//e:=sys_umtx_op(@mtx,UMTX_OP_MUTEX_LOCK,td.td_tid,nil,nil);
|
||||
e:=sys_umtx_op(@rwl,UMTX_OP_RW_WRLOCK,0,nil,nil);
|
||||
Writeln(' lock[',GetCurrentThreadId,'] ',e);
|
||||
|
||||
//e:=_do_lock_normal(GetCurrentThreadId,@mtx,0,NT_INFINITE,0);
|
||||
|
@ -54,7 +56,8 @@ begin
|
|||
//sleep(100);
|
||||
|
||||
//e:=sys_umtx_op(@mtx,{UMTX_OP_MUTEX_UNLOCK} UMTX_OP_UNLOCK,td.td_tid,nil,nil);
|
||||
e:=sys_umtx_op(@mtx,UMTX_OP_MUTEX_UNLOCK,td.td_tid,nil,nil);
|
||||
//e:=sys_umtx_op(@mtx,UMTX_OP_MUTEX_UNLOCK,td.td_tid,nil,nil);
|
||||
e:=sys_umtx_op(@rwl,UMTX_OP_RW_UNLOCK,0,nil,nil);
|
||||
Writeln('unlock[',GetCurrentThreadId,'] ',e);
|
||||
|
||||
sleep(1000)
|
||||
|
|
Loading…
Reference in New Issue