mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-30 23:33:17 +00:00
common: Rework timekeeping with native RDTSC and port to linux
This commit is contained in:
parent
acfa56f6bc
commit
fe43558779
37 changed files with 818 additions and 279 deletions
|
@ -1,5 +1,5 @@
|
|||
#include "gpu_memory.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <xxh3.h>
|
||||
|
||||
#include "common/singleton.h"
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
#include "common/types.h"
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <mutex>
|
||||
#include <memory>
|
||||
|
||||
namespace HLE::Libs::Graphics {
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -52,4 +54,4 @@ class HandleTable {
|
|||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
} // namespace Core::FileSys
|
||||
} // namespace Core::FileSys
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "common/debug.h"
|
||||
#include "common/timer.h"
|
||||
#include "core/hle/kernel/objects/event_queue.h"
|
||||
#include "core/hle/kernel/Objects/event_queue.h"
|
||||
|
||||
namespace Core::Kernel {
|
||||
|
||||
|
@ -24,28 +23,19 @@ int EqueueInternal::addEvent(const EqueueEvent& event) {
|
|||
|
||||
int EqueueInternal::waitForEvents(SceKernelEvent* ev, int num, u32 micros) {
|
||||
std::unique_lock lock{m_mutex};
|
||||
int ret = 0;
|
||||
|
||||
u32 timeElapsed = 0;
|
||||
Common::Timer t;
|
||||
t.Start();
|
||||
const auto predicate = [&] {
|
||||
ret = getTriggeredEvents(ev, num);
|
||||
return ret > 0;
|
||||
};
|
||||
|
||||
for (;;) {
|
||||
int ret = getTriggeredEvents(ev, num);
|
||||
|
||||
if (ret > 0 || (timeElapsed >= micros && micros != 0)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (micros == 0) {
|
||||
m_cond.wait(lock);
|
||||
} else {
|
||||
m_cond.wait_for(lock, std::chrono::microseconds(micros - timeElapsed));
|
||||
}
|
||||
|
||||
timeElapsed = static_cast<uint32_t>(t.GetTimeSec() * 1000000.0);
|
||||
if (micros == 0) {
|
||||
m_cond.wait(lock, predicate);
|
||||
} else {
|
||||
m_cond.wait_for(lock, std::chrono::microseconds(micros), predicate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool EqueueInternal::triggerEvent(u64 ident, s16 filter, void* trigger_data) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <condition_variable>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Kernel {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "core/hle/kernel/objects/physical_memory.h"
|
||||
#include "core/hle/kernel/Objects/physical_memory.h"
|
||||
|
||||
namespace Core::Kernel {
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/objects/event_queue.h"
|
||||
#include "core/hle/kernel/Objects/event_queue.h"
|
||||
|
||||
namespace Core::Kernel {
|
||||
|
||||
|
|
|
@ -4,35 +4,35 @@
|
|||
namespace Core::Libraries::LibC {
|
||||
|
||||
float PS4_SYSV_ABI ps4_atan2f(float y, float x) {
|
||||
return std::atan2f(y, x);
|
||||
return atan2f(y, x);
|
||||
}
|
||||
|
||||
float PS4_SYSV_ABI ps4_acosf(float num) {
|
||||
return std::acosf(num);
|
||||
return acosf(num);
|
||||
}
|
||||
|
||||
float PS4_SYSV_ABI ps4_tanf(float num) {
|
||||
return std::tanf(num);
|
||||
return tanf(num);
|
||||
}
|
||||
|
||||
float PS4_SYSV_ABI ps4_asinf(float num) {
|
||||
return std::asinf(num);
|
||||
return asinf(num);
|
||||
}
|
||||
|
||||
double PS4_SYSV_ABI ps4_pow(double base, double exponent) {
|
||||
return std::pow(base, exponent);
|
||||
return pow(base, exponent);
|
||||
}
|
||||
|
||||
double PS4_SYSV_ABI ps4__Sin(double x) {
|
||||
return std::sin(x);
|
||||
return sin(x);
|
||||
}
|
||||
|
||||
float PS4_SYSV_ABI ps4__Fsin(float arg) {
|
||||
return std::sinf(arg);
|
||||
return sinf(arg);
|
||||
}
|
||||
|
||||
double PS4_SYSV_ABI ps4_exp2(double arg) {
|
||||
return std::exp2(arg);
|
||||
return exp2(arg);
|
||||
}
|
||||
|
||||
} // namespace Core::Libraries::LibC
|
||||
|
|
|
@ -12,7 +12,7 @@ int PS4_SYSV_ABI ps4_printf(VA_ARGS) {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI ps4_fprintf(FILE* file, VA_ARGS) {
|
||||
int fd = _fileno(file);
|
||||
int fd = fileno(file);
|
||||
if (fd == 1 || fd == 2) { // output stdout and stderr to console
|
||||
VA_CTX(ctx);
|
||||
return printf_ctx(&ctx);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#ifdef _WIN64
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#include "thread_management.h"
|
||||
|
||||
|
@ -56,6 +58,7 @@ int* PS4_SYSV_ABI __Error() { return &libc_error; }
|
|||
#define PROT_WRITE 0x2
|
||||
|
||||
int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, off_t offset, void** res) {
|
||||
#ifdef _WIN64
|
||||
PRINT_FUNCTION_NAME();
|
||||
if (prot > 3) // READ,WRITE or bitwise READ | WRITE supported
|
||||
{
|
||||
|
@ -86,6 +89,14 @@ int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd,
|
|||
}
|
||||
*res = ret;
|
||||
return 0;
|
||||
#else
|
||||
void* result = mmap(addr, len, prot, flags, fd, offset);
|
||||
if (result != MAP_FAILED) {
|
||||
*res = result;
|
||||
return 0;
|
||||
}
|
||||
std::abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
PS4_SYSV_ABI void* posix_mmap(void* addr, u64 len, int prot, int flags, int fd, u64 offset) {
|
||||
|
|
|
@ -1,27 +1,31 @@
|
|||
#include "common/timer.h"
|
||||
#include "common/native_clock.h"
|
||||
#include "core/hle/libraries/libkernel/time_management.h"
|
||||
#include "core/hle/libraries/libs.h"
|
||||
#include "emuTimer.h"
|
||||
|
||||
namespace Core::Libraries::LibKernel {
|
||||
|
||||
static u64 initial_ptc;
|
||||
static std::unique_ptr<Common::NativeClock> clock;
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelGetProcessTime() {
|
||||
return static_cast<u64>(Emulator::emuTimer::getTimeMsec() * 1000.0); // return time in microseconds
|
||||
return clock->GetProcessTimeUS();
|
||||
}
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter() {
|
||||
return Emulator::emuTimer::getTimeCounter();
|
||||
return clock->GetUptime() - initial_ptc;
|
||||
}
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounterFrequency() {
|
||||
return Emulator::emuTimer::getTimeFrequency();
|
||||
return clock->GetTscFrequency();
|
||||
}
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelReadTsc() {
|
||||
return Common::Timer::getQueryPerformanceCounter();
|
||||
return clock->GetUptime();
|
||||
}
|
||||
|
||||
void timeSymbolsRegister(Loader::SymbolsResolver* sym) {
|
||||
clock = std::make_unique<Common::NativeClock>();
|
||||
initial_ptc = clock->GetUptime();
|
||||
LIB_FUNCTION("4J2sUJmuHZQ", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTime);
|
||||
LIB_FUNCTION("fgxnMeTNUtY", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTimeCounter);
|
||||
LIB_FUNCTION("BNowx2l588E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcessTimeCounterFrequency);
|
||||
|
|
|
@ -658,12 +658,12 @@ void Linker::Resolve(const std::string& name, int Symtype, Module* m, Loader::Sy
|
|||
}
|
||||
else
|
||||
{
|
||||
__debugbreak();//den tha prepei na ftasoume edo
|
||||
//__debugbreak();//den tha prepei na ftasoume edo
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__debugbreak();//oute edo mallon
|
||||
//__debugbreak();//oute edo mallon
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
namespace Core::Loader {
|
||||
|
||||
constexpr bool log_file_loader = true; // disable it to disable logging
|
||||
constexpr bool log_file_loader = false; // disable it to disable logging
|
||||
|
||||
static std::string_view getProgramTypeName(program_type_es type) {
|
||||
switch (type) {
|
||||
|
|
|
@ -79,7 +79,8 @@ bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode
|
|||
}
|
||||
return true;
|
||||
#else
|
||||
#error Unimplement memory_protect function
|
||||
int ret = mprotect(reinterpret_cast<void*>(address), size, convertMemoryMode(mode));
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -117,6 +118,7 @@ bool memory_patch(u64 vaddr, u64 value) {
|
|||
static u64 AlignUp(u64 pos, u64 align) { return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos); }
|
||||
|
||||
u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment) {
|
||||
#ifdef _WIN64
|
||||
// try allocate aligned address inside user area
|
||||
MEM_ADDRESS_REQUIREMENTS req{};
|
||||
MEM_EXTENDED_PARAMETER param{};
|
||||
|
@ -134,5 +136,13 @@ u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment)
|
|||
LOG_ERROR_IF(true, "VirtualAlloc2() failed: 0x{:X}\n", err);
|
||||
}
|
||||
return ptr;
|
||||
#else
|
||||
void* hint_address = reinterpret_cast<void*>(AlignUp(address, alignment));
|
||||
void* ptr = mmap(hint_address, size, convertMemoryMode(mode), MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
if (ptr == MAP_FAILED) {
|
||||
std::abort();
|
||||
}
|
||||
return reinterpret_cast<u64>(ptr);
|
||||
#endif
|
||||
}
|
||||
} // namespace VirtualMemory
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue