mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-10-11 21:49:59 +00:00
Races and leak fixes part 2 (#4241)
* fixed Unsynchronized free_threads.size()` Read in ThreadState::Free * fixed data race in posix_pthread_key_create , allocated and seqno are atomic now * fixed playtime thread * argv array size fix * destroy mutex on object deletion with pthread_mutex_destroy * fixed object_pool
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
@@ -12,6 +12,13 @@ namespace Common {
|
||||
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||
class AdaptiveMutex {
|
||||
public:
|
||||
AdaptiveMutex() = default;
|
||||
~AdaptiveMutex() {
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
AdaptiveMutex(const AdaptiveMutex&) = delete;
|
||||
AdaptiveMutex& operator=(const AdaptiveMutex&) = delete;
|
||||
|
||||
void lock() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
|
||||
@@ -77,9 +77,7 @@ private:
|
||||
}
|
||||
|
||||
void Release() {
|
||||
for (size_t i = 0; i < used_objects; i++) {
|
||||
storage[i].object.~T();
|
||||
}
|
||||
std::destroy_n(storage.get(), used_objects);
|
||||
used_objects = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
@@ -212,8 +212,8 @@ struct PthreadSpecificElem {
|
||||
using PthreadKeyDestructor = void PS4_SYSV_ABI (*)(const void*);
|
||||
|
||||
struct PthreadKey {
|
||||
int allocated;
|
||||
int seqno;
|
||||
std::atomic<int> allocated;
|
||||
std::atomic<int> seqno;
|
||||
PthreadKeyDestructor destructor;
|
||||
};
|
||||
using PthreadKeyT = s32;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "core/libraries/kernel/kernel.h"
|
||||
@@ -16,7 +16,8 @@ static std::mutex KeytableLock;
|
||||
|
||||
int PS4_SYSV_ABI posix_pthread_key_create(PthreadKeyT* key, PthreadKeyDestructor destructor) {
|
||||
std::scoped_lock lk{KeytableLock};
|
||||
const auto it = std::ranges::find(ThreadKeytable, 0, &PthreadKey::allocated);
|
||||
const auto it = std::ranges::find_if(
|
||||
ThreadKeytable, [](const PthreadKey& k) { return k.allocated.load() == 0; });
|
||||
if (it != ThreadKeytable.end()) {
|
||||
it->allocated = 1;
|
||||
it->destructor = destructor;
|
||||
|
||||
@@ -127,13 +127,20 @@ void ThreadState::Free(Pthread* curthread, Pthread* thread) {
|
||||
thread->tcb = nullptr;
|
||||
auto* sleepqueue = thread->sleepqueue;
|
||||
std::destroy_at(thread);
|
||||
if (free_threads.size() >= MaxCachedThreads) {
|
||||
bool should_free;
|
||||
{
|
||||
std::scoped_lock lk{free_thread_lock};
|
||||
if (free_threads.size() >= MaxCachedThreads) {
|
||||
should_free = true;
|
||||
} else {
|
||||
should_free = false;
|
||||
free_threads.push_back(thread);
|
||||
}
|
||||
}
|
||||
if (should_free) {
|
||||
delete sleepqueue;
|
||||
thread_heap.Free(thread);
|
||||
total_threads.fetch_sub(1);
|
||||
} else {
|
||||
std::scoped_lock lk{free_thread_lock};
|
||||
free_threads.push_back(thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -140,8 +140,9 @@ void Linker::Execute(const std::vector<std::string>& args) {
|
||||
params.argc = 1;
|
||||
params.argv[0] = "eboot.bin";
|
||||
if (!args.empty()) {
|
||||
params.argc = args.size();
|
||||
for (int i = 0; i < args.size() && i < 33; i++) {
|
||||
constexpr int MaxArgs = sizeof(params.argv) / sizeof(params.argv[0]);
|
||||
params.argc = std::min<int>(args.size(), MaxArgs);
|
||||
for (int i = 0; i < params.argc; i++) {
|
||||
params.argv[i] = args[i].c_str();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -445,13 +445,12 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
|
||||
if (!id.empty()) {
|
||||
start_time = std::chrono::steady_clock::now();
|
||||
|
||||
std::thread([this, id]() {
|
||||
while (true) {
|
||||
std::this_thread::sleep_for(std::chrono::seconds(60));
|
||||
play_time_thread = std::jthread([this, id](std::stop_token stop) {
|
||||
while (Common::StoppableTimedWait(stop, std::chrono::seconds(60))) {
|
||||
UpdatePlayTime(id);
|
||||
start_time = std::chrono::steady_clock::now();
|
||||
}
|
||||
}).detach();
|
||||
});
|
||||
}
|
||||
|
||||
args.insert(args.begin(), eboot_name.generic_string());
|
||||
|
||||
@@ -47,6 +47,7 @@ private:
|
||||
Core::Linker* linker;
|
||||
std::unique_ptr<Frontend::WindowSDL> window;
|
||||
std::chrono::steady_clock::time_point start_time;
|
||||
std::jthread play_time_thread;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
Reference in New Issue
Block a user