mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-16 08:42:32 +00:00
Bugfix
This commit is contained in:
parent
5e14310071
commit
e551e2bc5d
@ -28,8 +28,6 @@
|
|||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||||
#define alignas(x) _CRT_ALIGN(x)
|
#define alignas(x) _CRT_ALIGN(x)
|
||||||
#elif defined(__GNUG__)
|
|
||||||
#define ALIGN(x) __attribute__((aligned(x))) // not used
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GNUG__)
|
#if defined(__GNUG__)
|
||||||
@ -83,7 +81,7 @@ int clock_gettime(clockid_t clk_id, struct timespec *tp);
|
|||||||
#endif /* __GNUG__ */
|
#endif /* __GNUG__ */
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
// Unsigned 128-bit number implementation
|
// Unsigned 128-bit integer implementation
|
||||||
struct alignas(16) uint128_t
|
struct alignas(16) uint128_t
|
||||||
{
|
{
|
||||||
uint64_t lo, hi;
|
uint64_t lo, hi;
|
||||||
|
@ -248,7 +248,7 @@ namespace fmt
|
|||||||
// pointer to the current buffer
|
// pointer to the current buffer
|
||||||
char* buf_addr = fixed_buf.data();
|
char* buf_addr = fixed_buf.data();
|
||||||
|
|
||||||
for (std::size_t buf_size = fixed_buf.size();; buf_size *= 2, buf.reset(buf_addr = new char[buf_size]))
|
for (std::size_t buf_size = fixed_buf.size();; buf.reset(buf_addr = new char[buf_size]))
|
||||||
{
|
{
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||||
@ -256,10 +256,17 @@ namespace fmt
|
|||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
if (len > INT_MAX)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("std::snprintf() failed");
|
||||||
|
}
|
||||||
|
|
||||||
if (len <= buf_size)
|
if (len <= buf_size)
|
||||||
{
|
{
|
||||||
return{ buf_addr, len };
|
return{ buf_addr, len };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf_size = len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,11 +292,6 @@ namespace fmt
|
|||||||
std::memcpy(message.get(), other, size + 1);
|
std::memcpy(message.get(), other, size + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
exception(exception&& other)
|
|
||||||
{
|
|
||||||
message = std::move(other.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator const char*() const
|
operator const char*() const
|
||||||
{
|
{
|
||||||
return message.get();
|
return message.get();
|
||||||
|
@ -1196,7 +1196,7 @@ const thread_ctrl_t* get_current_thread_ctrl()
|
|||||||
|
|
||||||
std::string thread_ctrl_t::get_name() const
|
std::string thread_ctrl_t::get_name() const
|
||||||
{
|
{
|
||||||
return name();
|
return m_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
named_thread_t::named_thread_t(std::function<std::string()> name, std::function<void()> func)
|
named_thread_t::named_thread_t(std::function<std::string()> name, std::function<void()> func)
|
||||||
@ -1220,12 +1220,12 @@ std::string named_thread_t::get_name() const
|
|||||||
throw EXCEPTION("Invalid thread");
|
throw EXCEPTION("Invalid thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_thread->name)
|
if (!m_thread->m_name)
|
||||||
{
|
{
|
||||||
throw EXCEPTION("Invalid name getter");
|
throw EXCEPTION("Invalid name getter");
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_thread->name();
|
return m_thread->m_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::atomic<u32> g_thread_count{ 0 };
|
std::atomic<u32> g_thread_count{ 0 };
|
||||||
@ -1296,6 +1296,13 @@ void named_thread_t::start(std::function<std::string()> name, std::function<void
|
|||||||
LOG_NOTICE(GENERAL, "Thread aborted");
|
LOG_NOTICE(GENERAL, "Thread aborted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& func : ctrl->m_atexit)
|
||||||
|
{
|
||||||
|
func();
|
||||||
|
|
||||||
|
func = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
vm::reservation_free();
|
vm::reservation_free();
|
||||||
|
|
||||||
g_thread_count--;
|
g_thread_count--;
|
||||||
|
@ -7,15 +7,20 @@ class thread_ctrl_t final
|
|||||||
{
|
{
|
||||||
friend class named_thread_t;
|
friend class named_thread_t;
|
||||||
|
|
||||||
|
template<typename T> friend void current_thread_register_atexit(T);
|
||||||
|
|
||||||
// thread handler
|
// thread handler
|
||||||
std::thread m_thread;
|
std::thread m_thread;
|
||||||
|
|
||||||
// name getter
|
// name getter
|
||||||
const std::function<std::string()> name;
|
const std::function<std::string()> m_name;
|
||||||
|
|
||||||
|
// functions executed at thread exit (temporarily)
|
||||||
|
std::vector<std::function<void()>> m_atexit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
thread_ctrl_t(std::function<std::string()> name)
|
thread_ctrl_t(std::function<std::string()> name)
|
||||||
: name(std::move(name))
|
: m_name(std::move(name))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +28,14 @@ public:
|
|||||||
std::string get_name() const;
|
std::string get_name() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// register function at thread exit (temporarily)
|
||||||
|
template<typename T> void current_thread_register_atexit(T func)
|
||||||
|
{
|
||||||
|
extern thread_local thread_ctrl_t* g_tls_this_thread;
|
||||||
|
|
||||||
|
g_tls_this_thread->m_atexit.emplace_back(func);
|
||||||
|
}
|
||||||
|
|
||||||
class named_thread_t
|
class named_thread_t
|
||||||
{
|
{
|
||||||
// pointer to managed resource (shared with actual thread)
|
// pointer to managed resource (shared with actual thread)
|
||||||
|
@ -25,7 +25,8 @@ u64 rotate_mask[64][64];
|
|||||||
extern u32 ppu_get_tls(u32 thread);
|
extern u32 ppu_get_tls(u32 thread);
|
||||||
extern void ppu_free_tls(u32 thread);
|
extern void ppu_free_tls(u32 thread);
|
||||||
|
|
||||||
thread_local const std::weak_ptr<ppu_decoder_cache_t> g_tls_ppu_decoder_cache = fxm::get<ppu_decoder_cache_t>();
|
//thread_local const std::weak_ptr<ppu_decoder_cache_t> g_tls_ppu_decoder_cache = fxm::get<ppu_decoder_cache_t>();
|
||||||
|
thread_local const ppu_decoder_cache_t* g_tls_ppu_decoder_cache = nullptr; // temporarily, because thread_local is not fully available
|
||||||
|
|
||||||
ppu_decoder_cache_t::ppu_decoder_cache_t()
|
ppu_decoder_cache_t::ppu_decoder_cache_t()
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -285,14 +286,19 @@ void PPUThread::task()
|
|||||||
return custom_task(*this);
|
return custom_task(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto decoder_cache = g_tls_ppu_decoder_cache.lock();
|
if (!g_tls_ppu_decoder_cache)
|
||||||
|
|
||||||
if (!decoder_cache)
|
|
||||||
{
|
{
|
||||||
throw EXCEPTION("PPU Decoder Cache not initialized");
|
const auto decoder_cache = fxm::get<ppu_decoder_cache_t>();
|
||||||
}
|
|
||||||
|
|
||||||
const auto exec_map = decoder_cache->pointer;
|
if (!decoder_cache)
|
||||||
|
{
|
||||||
|
throw EXCEPTION("PPU Decoder Cache not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
g_tls_ppu_decoder_cache = decoder_cache.get(); // unsafe (TODO)
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto exec_map = g_tls_ppu_decoder_cache->pointer;
|
||||||
|
|
||||||
if (m_dec)
|
if (m_dec)
|
||||||
{
|
{
|
||||||
|
@ -833,7 +833,17 @@ s32 cellFsSdataOpen(PPUThread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<u32>
|
|||||||
return CELL_FS_EINVAL;
|
return CELL_FS_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cellFsOpen(path, CELL_FS_O_RDONLY, fd, vm::var<u64>(ppu), 8);
|
struct _arg_t
|
||||||
|
{
|
||||||
|
be_t<u32> a, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
const vm::var<_arg_t> _arg(ppu);
|
||||||
|
|
||||||
|
_arg->a = 0x180;
|
||||||
|
_arg->b = 0x10;
|
||||||
|
|
||||||
|
return cellFsOpen(path, CELL_FS_O_RDONLY, fd, _arg, 8);
|
||||||
|
|
||||||
// Don't implement sdata decryption in this function, it should be done in sys_fs_open() syscall or somewhere else
|
// Don't implement sdata decryption in this function, it should be done in sys_fs_open() syscall or somewhere else
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ s32 cellGameDataCheck(u32 type, vm::cptr<char> dirName, vm::ptr<CellGameContentS
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const std::string dir = std::string("/dev_hdd0/game/") + dirName.get_ptr();
|
const std::string dir = "/dev_hdd0/game/"s + dirName.get_ptr();
|
||||||
|
|
||||||
if (!Emu.GetVFS().ExistsDir(dir))
|
if (!Emu.GetVFS().ExistsDir(dir))
|
||||||
{
|
{
|
||||||
@ -388,7 +388,7 @@ s32 cellGameDataCheckCreate2(PPUThread& ppu, u32 version, vm::cptr<char> dirName
|
|||||||
|
|
||||||
// TODO: output errors (errDialog)
|
// TODO: output errors (errDialog)
|
||||||
|
|
||||||
const std::string dir = std::string("/dev_hdd0/game/") + dirName.get_ptr();
|
const std::string dir = "/dev_hdd0/game/"s + dirName.get_ptr();
|
||||||
|
|
||||||
if (!Emu.GetVFS().ExistsDir(dir))
|
if (!Emu.GetVFS().ExistsDir(dir))
|
||||||
{
|
{
|
||||||
|
@ -212,7 +212,7 @@ s32 cellSysCacheClear(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string localPath;
|
std::string localPath;
|
||||||
Emu.GetVFS().GetDevice(std::string("/dev_hdd1/cache/"), localPath);
|
Emu.GetVFS().GetDevice("/dev_hdd1/cache/", localPath);
|
||||||
|
|
||||||
// TODO: Write tests to figure out, what is deleted.
|
// TODO: Write tests to figure out, what is deleted.
|
||||||
|
|
||||||
@ -226,9 +226,9 @@ s32 cellSysCacheMount(vm::ptr<CellSysCacheParam> param)
|
|||||||
// TODO: implement
|
// TODO: implement
|
||||||
char id[CELL_SYSCACHE_ID_SIZE];
|
char id[CELL_SYSCACHE_ID_SIZE];
|
||||||
strncpy(id, param->cacheId, CELL_SYSCACHE_ID_SIZE);
|
strncpy(id, param->cacheId, CELL_SYSCACHE_ID_SIZE);
|
||||||
strncpy(param->getCachePath, ("/dev_hdd1/cache/" + std::string(id) + "/").c_str(), CELL_SYSCACHE_PATH_MAX);
|
strncpy(param->getCachePath, ("/dev_hdd1/cache/"s + id + "/").c_str(), CELL_SYSCACHE_PATH_MAX);
|
||||||
param->getCachePath[CELL_SYSCACHE_PATH_MAX - 1] = '\0';
|
param->getCachePath[CELL_SYSCACHE_PATH_MAX - 1] = '\0';
|
||||||
Emu.GetVFS().CreateDir(std::string(param->getCachePath));
|
Emu.GetVFS().CreateDir(param->getCachePath);
|
||||||
g_sysutil->cacheMounted.exchange(true);
|
g_sysutil->cacheMounted.exchange(true);
|
||||||
|
|
||||||
return CELL_SYSCACHE_RET_OK_RELAYED;
|
return CELL_SYSCACHE_RET_OK_RELAYED;
|
||||||
|
@ -118,13 +118,20 @@ namespace sys_net
|
|||||||
be_t<s32> _h_errno;
|
be_t<s32> _h_errno;
|
||||||
};
|
};
|
||||||
|
|
||||||
thread_local vm::var<_tls_data_t, vm::page_alloc_t> g_tls_net_data;
|
// TODO
|
||||||
|
thread_local vm::ptr<_tls_data_t> g_tls_net_data{};
|
||||||
|
|
||||||
inline void initialize_tls()
|
inline void initialize_tls()
|
||||||
{
|
{
|
||||||
|
// allocate if not initialized
|
||||||
if (!g_tls_net_data)
|
if (!g_tls_net_data)
|
||||||
{
|
{
|
||||||
g_tls_net_data = { vm::main }; // allocate if not initialized
|
g_tls_net_data.set(vm::alloc(sizeof(decltype(g_tls_net_data)::type), vm::main));
|
||||||
|
|
||||||
|
current_thread_register_atexit([addr = g_tls_net_data.addr()]
|
||||||
|
{
|
||||||
|
vm::dealloc_verbose_nothrow(addr, vm::main);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,9 +40,9 @@ s32 sys_mmapper_allocate_address(u64 size, u64 flags, u64 alignment, vm::ptr<u32
|
|||||||
case 0x40000000:
|
case 0x40000000:
|
||||||
case 0x80000000:
|
case 0x80000000:
|
||||||
{
|
{
|
||||||
for (u32 addr = ::align(0x30000000, alignment); addr < 0xC0000000; addr += static_cast<u32>(alignment))
|
for (u64 addr = ::align<u64>(0x30000000, alignment); addr < 0xC0000000; addr += alignment)
|
||||||
{
|
{
|
||||||
if (const auto area = vm::map(addr, static_cast<u32>(size), flags))
|
if (const auto area = vm::map(static_cast<u32>(addr), static_cast<u32>(size), flags))
|
||||||
{
|
{
|
||||||
*alloc_addr = addr;
|
*alloc_addr = addr;
|
||||||
|
|
||||||
@ -273,9 +273,9 @@ s32 sys_mmapper_map_memory(u32 addr, u32 mem_id, u64 flags)
|
|||||||
return CELL_EALIGN;
|
return CELL_EALIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mem->addr)
|
if (const u32 old_addr = mem->addr.load())
|
||||||
{
|
{
|
||||||
throw EXCEPTION("Already mapped (mem_id=0x%x, addr=0x%x)", mem_id, mem->addr.load());
|
throw EXCEPTION("Already mapped (mem_id=0x%x, addr=0x%x)", mem_id, old_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!area->falloc(addr, mem->size))
|
if (!area->falloc(addr, mem->size))
|
||||||
@ -322,7 +322,7 @@ s32 sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, vm::ptr<u3
|
|||||||
|
|
||||||
s32 sys_mmapper_unmap_memory(u32 addr, vm::ptr<u32> mem_id)
|
s32 sys_mmapper_unmap_memory(u32 addr, vm::ptr<u32> mem_id)
|
||||||
{
|
{
|
||||||
sys_mmapper.Todo("sys_mmapper_unmap_memory(addr=0x%x, mem_id=*0x%x)", addr, mem_id);
|
sys_mmapper.Error("sys_mmapper_unmap_memory(addr=0x%x, mem_id=*0x%x)", addr, mem_id);
|
||||||
|
|
||||||
LV2_LOCK;
|
LV2_LOCK;
|
||||||
|
|
||||||
@ -339,7 +339,7 @@ s32 sys_mmapper_unmap_memory(u32 addr, vm::ptr<u32> mem_id)
|
|||||||
{
|
{
|
||||||
if (!area->dealloc(addr))
|
if (!area->dealloc(addr))
|
||||||
{
|
{
|
||||||
throw EXCEPTION("Not mapped (mem_id=0x%x, addr=0x%x)", mem->id, addr);
|
throw EXCEPTION("Deallocation failed (mem_id=0x%x, addr=0x%x)", mem->id, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
mem->addr = 0;
|
mem->addr = 0;
|
||||||
|
@ -148,7 +148,7 @@ namespace loader
|
|||||||
char name[27];
|
char name[27];
|
||||||
m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + lib.name_addr);
|
m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + lib.name_addr);
|
||||||
m_stream->Read(name, sizeof(name));
|
m_stream->Read(name, sizeof(name));
|
||||||
modulename = std::string(name);
|
modulename = name;
|
||||||
LOG_WARNING(LOADER, "**** Exported: %s", name);
|
LOG_WARNING(LOADER, "**** Exported: %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ namespace loader
|
|||||||
char name[27];
|
char name[27];
|
||||||
m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + lib.name_addr);
|
m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + lib.name_addr);
|
||||||
m_stream->Read(name, sizeof(name));
|
m_stream->Read(name, sizeof(name));
|
||||||
modulename = std::string(name);
|
modulename = name;
|
||||||
LOG_WARNING(LOADER, "**** Imported: %s", name);
|
LOG_WARNING(LOADER, "**** Imported: %s", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,12 +41,15 @@
|
|||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
|
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
#include "Utilities/GNU.h"
|
#include "Utilities/GNU.h"
|
||||||
|
|
||||||
#define CHECK_SIZE(type, size) static_assert(sizeof(type) == size, "Invalid " #type " type size")
|
#define CHECK_SIZE(type, size) static_assert(sizeof(type) == size, "Invalid " #type " type size")
|
||||||
#define CHECK_ALIGN(type, align) static_assert(__alignof(type) == align, "Invalid " #type " type alignment")
|
#define CHECK_ALIGN(type, align) static_assert(__alignof(type) == align, "Invalid " #type " type alignment")
|
||||||
#define CHECK_MAX_SIZE(type, size) static_assert(sizeof(type) <= size, #type " type size is too big")
|
#define CHECK_MAX_SIZE(type, size) static_assert(sizeof(type) <= size, #type " type size is too big")
|
||||||
#define CHECK_SIZE_ALIGN(type, size, align) CHECK_SIZE(type, size); CHECK_ALIGN(type, align)
|
#define CHECK_SIZE_ALIGN(type, size, align) CHECK_SIZE(type, size); CHECK_ALIGN(type, align)
|
||||||
|
#define CHECK_ASCENDING(constexpr_array) static_assert(::is_ascending(constexpr_array), #constexpr_array " is not sorted in ascending order")
|
||||||
|
|
||||||
using uint = unsigned int;
|
using uint = unsigned int;
|
||||||
|
|
||||||
@ -107,6 +110,18 @@ template<std::size_t N, std::size_t N2> inline void strcpy_trunc(char(&dst)[N],
|
|||||||
dst[count] = '\0';
|
dst[count] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns true if all array elements are unique and sorted in ascending order
|
||||||
|
template<typename T, std::size_t N> constexpr bool is_ascending(const T(&array)[N], std::size_t from = 0)
|
||||||
|
{
|
||||||
|
return from >= N - 1 ? true : array[from] < array[from + 1] ? is_ascending(array, from + 1) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get (first) array element equal to `value` or nullptr if not found
|
||||||
|
template<typename T, std::size_t N, typename T2> constexpr const T* static_search(const T(&array)[N], const T2& value, std::size_t from = 0)
|
||||||
|
{
|
||||||
|
return from >= N ? nullptr : array[from] == value ? array + from : static_search(array, value, from + 1);
|
||||||
|
}
|
||||||
|
|
||||||
// bool wrapper for restricting bool result conversions
|
// bool wrapper for restricting bool result conversions
|
||||||
struct explicit_bool_t
|
struct explicit_bool_t
|
||||||
{
|
{
|
||||||
@ -123,6 +138,18 @@ struct explicit_bool_t
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T1, typename T2, typename T3 = const char*> struct triplet_t
|
||||||
|
{
|
||||||
|
T1 first;
|
||||||
|
T2 second;
|
||||||
|
T3 third;
|
||||||
|
|
||||||
|
constexpr bool operator ==(const T1& right) const
|
||||||
|
{
|
||||||
|
return first == right;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// return 32 bit sizeof() to avoid widening/narrowing conversions with size_t
|
// return 32 bit sizeof() to avoid widening/narrowing conversions with size_t
|
||||||
#define sizeof32(type) static_cast<u32>(sizeof(type))
|
#define sizeof32(type) static_cast<u32>(sizeof(type))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user