diff --git a/chip/ps4_videodrv.pas b/chip/ps4_videodrv.pas index 06fd63e5..f92ec017 100644 --- a/chip/ps4_videodrv.pas +++ b/chip/ps4_videodrv.pas @@ -627,7 +627,7 @@ begin ResetEvent(FIdleEvent); GFXRing.Queue.Push(node); - NtQueueApcThread(_gfx_handle,@_apc_null,0,nil,0); + NtQueueApcThread(_gfx_handle,@_apc_null,nil,nil,0); end; procedure vSubmitDone; diff --git a/kernel/ps4_map_mm.pas b/kernel/ps4_map_mm.pas index e3d6791b..4feaceb4 100644 --- a/kernel/ps4_map_mm.pas +++ b/kernel/ps4_map_mm.pas @@ -40,8 +40,12 @@ User area : 0x0010 0000 0000 - 0x00FC 0000 0000 Size: 0x00EC 0000 0000 System reserved area: 0x00FC 0000 0000 - 0x00FF FFFF FFFF Size: 0x0003 FFFF FFFF (15GB) } +//FFFF FF|FF FFFF FFFF +//0000 00|FF FFFF FFFF +//mirror |addr + var - MMLock:TRWLock; + MMLock:System.TRTLCriticalSection; DirectManager :TDirectManager; VirtualManager:TVirtualManager; @@ -293,6 +297,21 @@ uses sys_kernel, sys_signal; +Procedure INIT_MLOCK; inline; +begin + System.InitCriticalSection(MMLock); +end; + +Procedure MLOCK; inline; +begin + System.EnterCriticalSection(MMLock); +end; + +Procedure MUNLOCK; inline; +begin + System.LeaveCriticalSection(MMLock); +end; + function IsPowerOfTwo(x:QWORD):Boolean; inline; begin Result:=(x and (x - 1))=0; @@ -335,7 +354,7 @@ begin pb:=nil; - rwlock_rdlock(MMLock); + MLOCK; if VirtualManager.TryGetMapBlockByAddr(addr,pb) then begin @@ -356,7 +375,7 @@ begin end; __exit: - rwlock_unlock(MMLock); + MUNLOCK; end; function __free_block(block:PVirtualAdrBlock):Integer; @@ -377,21 +396,21 @@ Procedure RegistredStack; //var // block:PBlock; begin - //rwlock_wrlock(MMLock); + //MLOCK; //block:=AllocMem(SizeOf(TBlock)); //if (block=nil) then Exit; //block^.pAddr:=StackBottom; //block^.nSize:=StackLength; //block^.bType:=BT_STACK; //PageMM.FMapBlockSet.Insert(block); - //rwlock_unlock(MMLock); + //MUNLOCK; end; Procedure UnRegistredStack; begin - //rwlock_wrlock(MMLock); + //MLOCK; //PageMM._DeleteBlockByAddr(StackBottom); - //rwlock_unlock(MMLock); + //MUNLOCK; end; function ps4_sceKernelGetDirectMemorySize:Int64; SysV_ABI_CDecl; @@ -418,11 +437,11 @@ begin end; _sig_lock; - rwlock_rdlock(MMLock); //r + MLOCK; flex:=VirtualManager.stat.flex; - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; if (flex0 then //reserved begin @@ -870,7 +889,7 @@ begin end; end; - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; end; @@ -907,7 +926,7 @@ begin Result:=0; _sig_lock; - rwlock_wrlock(MMLock); //rw + MLOCK; Result:=DirectManager.CheckedMMap(physicalAddr,length); @@ -921,7 +940,7 @@ begin end; end; - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; end; @@ -950,7 +969,7 @@ begin Result:=EINVAL; _sig_lock; - rwlock_wrlock(MMLock); //rw + MLOCK; Result:=VirtualManager.Release(addr,len,False); @@ -959,7 +978,7 @@ begin NamedManager.Mname(addr,len,nil); end; - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; end; @@ -968,11 +987,11 @@ begin Result:=EINVAL; _sig_lock; - rwlock_wrlock(MMLock); //rw + MLOCK; Result:=VirtualManager.Protect(addr,len,prot); - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; end; @@ -981,11 +1000,11 @@ begin Result:=EINVAL; _sig_lock; - rwlock_wrlock(MMLock); //rw + MLOCK; Result:=VirtualManager.Mtypeprotect(addr,len,mtype,prot); - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; end; @@ -1000,11 +1019,11 @@ begin ROut:=Default(TVirtualAdrNode); _sig_lock; - rwlock_rdlock(MMLock); //r + MLOCK; Result:=VirtualManager.QueryProt(addr,ROut); - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; if (Result=0) then @@ -1046,7 +1065,7 @@ begin Name:=Default(TName); _sig_lock; - rwlock_rdlock(MMLock); //r + MLOCK; Result:=VirtualManager.Query(addr,(flags=SCE_KERNEL_VQ_FIND_NEXT),VOut); @@ -1060,7 +1079,7 @@ begin NamedManager.Query(addr,@name); end; - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; info^:=Default(SceKernelVirtualQueryInfo); @@ -1090,11 +1109,11 @@ begin if (StrLen(pname)>32) then Exit; _sig_lock; - rwlock_rdlock(MMLock); //r + MLOCK; Result:=NamedManager.Mname(addr,len,pname); - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; end; @@ -1680,7 +1699,7 @@ function ps4_sceKernelBatchMap2( numberOfEntriesOut:PInteger; flags:Integer):Integer; SysV_ABI_CDecl; label - _exit; + _exit,_exit_lock; var i:Integer; begin @@ -1699,6 +1718,9 @@ begin goto _exit; end; + _sig_lock; + MLOCK; + For i:=0 to numberOfEntries-1 do begin Case entries[i].operation of @@ -1742,18 +1764,21 @@ begin numberOfEntries:=i; _set_errno(EINVAL); Result:=SCE_KERNEL_ERROR_EINVAL; - goto _exit; + goto _exit_lock; end; end; if (Result<>0) then begin numberOfEntries:=i; - goto _exit; + goto _exit_lock; end; end; + _exit_lock: + MUNLOCK; + _sig_unlock; _exit: if (numberOfEntriesOut<>nil) then numberOfEntriesOut^:=numberOfEntries; end; @@ -1763,11 +1788,11 @@ end; function _sys_check_mmaped(addr:Pointer;len:qword):Integer; begin _sig_lock; - rwlock_rdlock(MMLock); + MLOCK; Result:=VirtualManager.check_mmaped(addr,len); - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; end; @@ -1835,11 +1860,11 @@ begin if ((flags and MS_ASYNC)<>0) and ((flags and MS_INVALIDATE)<>0) then Exit(EINVAL); _sig_lock; - rwlock_rdlock(MMLock); + MLOCK; Result:=VirtualManager.check_mmaped(addr,len); - rwlock_unlock(MMLock); + MUNLOCK; _sig_unlock; if (Result=0) then @@ -1883,7 +1908,7 @@ begin end; initialization - rwlock_init(MMLock); + INIT_MLOCK; DirectManager :=TDirectManager .Create; DirectManager .OnMemoryUnmapCb:=@__munmap; diff --git a/rtl/ntapi.pas b/rtl/ntapi.pas index 109a818b..ae15b8ee 100644 --- a/rtl/ntapi.pas +++ b/rtl/ntapi.pas @@ -49,15 +49,19 @@ type Directory :WORD; end; + PIO_APC_ROUTINE=procedure(ApcContext:Pointer; + IoStatusBlock:PIO_STATUS_BLOCK; + Reserved:ULONG); stdcall; + function NtAlertThread(hThread:THandle):DWORD; stdcall; external 'ntdll'; function NtTestAlert():DWORD; stdcall; external 'ntdll'; function NtQueueApcThread( - hThread:THandle; - ApcRoutine:Pointer; - ApcRoutineContext:PTRUINT; - ApcStatusBlock:Pointer; - ApcReserved:ULONG + hThread :THandle; + ApcRoutine :Pointer; + ApcContext :Pointer; + IoStatusBlock:PIO_STATUS_BLOCK; + ApcReserved :ULONG ):DWORD; stdcall; external 'ntdll'; function NtYieldExecution():DWORD; stdcall; external 'ntdll'; diff --git a/sys/sys_file.pas b/sys/sys_file.pas index 44617d8c..4784776e 100644 --- a/sys/sys_file.pas +++ b/sys/sys_file.pas @@ -251,6 +251,7 @@ begin rwlock_wrlock(lock); e:=NtReadFile(Handle,0,nil,nil,@s,data,size,nil,nil); + if (e=STATUS_PENDING) then e:=NtWaitForSingleObject(Handle,False,nil); rwlock_unlock(lock); @@ -296,6 +297,7 @@ begin //--------------------- e:=NtReadFile(Handle,0,nil,nil,@s,data,size,@offset,nil); + if (e=STATUS_PENDING) then e:=NtWaitForSingleObject(Handle,False,nil); //--------------------------------------------- //if not _set_pos(Handle,p) then Assert(False); @@ -335,6 +337,7 @@ begin s:=Default(IO_STATUS_BLOCK); e:=NtReadFile(Handle,0,nil,nil,@s,v.iov_base,v.iov_len,nil,nil); + if (e=STATUS_PENDING) then e:=NtWaitForSingleObject(Handle,False,nil); e:=-ntf2px(e); @@ -388,6 +391,8 @@ begin s:=Default(IO_STATUS_BLOCK); e:=NtReadFile(Handle,0,nil,nil,@s,v.iov_base,v.iov_len,poffset,nil); + if (e=STATUS_PENDING) then e:=NtWaitForSingleObject(Handle,False,nil); + poffset:=nil; //reset e:=-ntf2px(e); @@ -425,6 +430,7 @@ begin rwlock_wrlock(lock); e:=NtWriteFile(Handle,0,nil,nil,@s,data,size,nil,nil); + if (e=STATUS_PENDING) then e:=NtWaitForSingleObject(Handle,False,nil); rwlock_unlock(lock); @@ -452,6 +458,7 @@ begin //--------------------- e:=NtWriteFile(Handle,0,nil,nil,@s,data,size,@offset,nil); + if (e=STATUS_PENDING) then e:=NtWaitForSingleObject(Handle,False,nil); //--------------------------------------------- //if not _set_pos(Handle,p) then Assert(False); diff --git a/sys/sys_signal.pas b/sys/sys_signal.pas index 1a1c6f2b..9dc0615a 100644 --- a/sys/sys_signal.pas +++ b/sys/sys_signal.pas @@ -877,7 +877,7 @@ begin end else if ((t^.sig._flag and ALERTABLE_FLAG)<>0) then //Alertable begin - NtQueueApcThread(t^.handle,@_apc_null,0,nil,0); + NtQueueApcThread(t^.handle,@_apc_null,nil,nil,0); NtResumeThread(t^.handle,nil);