1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

LV2: Move memory unlocking outside of mutex ownership and make it conditional

This commit is contained in:
Eladash 2022-07-26 09:26:25 +03:00 committed by Ivan
parent 122c6256ca
commit a17a6527f6
10 changed files with 49 additions and 13 deletions

View File

@ -1207,8 +1207,12 @@ namespace cpu_counter
void lv2_obj::sleep(cpu_thread& cpu, const u64 timeout, bool notify_later)
{
vm::temporary_unlock(cpu);
cpu_counter::remove(&cpu);
// Should already be performed when using this flag
if (!notify_later)
{
vm::temporary_unlock(cpu);
cpu_counter::remove(&cpu);
}
{
std::lock_guard lock{g_mutex};
sleep_unlocked(cpu, timeout, notify_later);
@ -1218,7 +1222,12 @@ void lv2_obj::sleep(cpu_thread& cpu, const u64 timeout, bool notify_later)
bool lv2_obj::awake(cpu_thread* const thread, bool notify_later, s32 prio)
{
vm::temporary_unlock();
// Too risky to postpone it in case the notified thread may wait for this thread to free its passive lock
if (!notify_later)
{
vm::temporary_unlock();
}
std::lock_guard lock(g_mutex);
return awake_unlocked(thread, notify_later, prio);
}

View File

@ -300,7 +300,7 @@ error_code sys_cond_wait(ppu_thread& ppu, u32 cond_id, u64 timeout)
return -1;
}
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(cond.mutex->mutex);

View File

@ -421,7 +421,7 @@ error_code sys_event_queue_receive(ppu_thread& ppu, u32 equeue_id, vm::ptr<sys_e
return CELL_EINVAL;
}
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(queue.mutex);

View File

@ -152,7 +152,7 @@ error_code sys_event_flag_wait(ppu_thread& ppu, u32 id, u64 bitptn, u32 mode, vm
return {};
}
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(flag.mutex);

View File

@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "sys_lwcond.h"
#include "Emu/IdManager.h"
@ -343,7 +343,7 @@ error_code _sys_lwcond_queue_wait(ppu_thread& ppu, u32 lwcond_id, u32 lwmutex_id
// Increment lwmutex's lwcond's waiters count
mutex->lwcond_waiters++;
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(cond.mutex);

View File

@ -146,7 +146,7 @@ error_code _sys_lwmutex_lock(ppu_thread& ppu, u32 lwmutex_id, u64 timeout)
return true;
}
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(mutex.mutex);

View File

@ -141,7 +141,7 @@ error_code sys_mutex_lock(ppu_thread& ppu, u32 mutex_id, u64 timeout)
if (result == CELL_EBUSY)
{
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(mutex.mutex);

View File

@ -114,7 +114,7 @@ error_code sys_rwlock_rlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
}
}
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(rwlock.mutex);
@ -346,7 +346,7 @@ error_code sys_rwlock_wlock(ppu_thread& ppu, u32 rw_lock_id, u64 timeout)
return val;
}
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(rwlock.mutex);

View File

@ -123,7 +123,7 @@ error_code sys_semaphore_wait(ppu_thread& ppu, u32 sem_id, u64 timeout)
}
}
lv2_obj::notify_all_t notify;
lv2_obj::notify_all_t notify(ppu);
std::lock_guard lock(sema.mutex);

View File

@ -61,6 +61,16 @@ enum
enum ppu_thread_status : u32;
namespace vm
{
void temporary_unlock(cpu_thread& cpu) noexcept;
}
namespace cpu_counter
{
void remove(cpu_thread*) noexcept;
}
// Base class for some kernel objects (shared set of 8192 objects).
struct lv2_obj
{
@ -495,10 +505,27 @@ public:
}
}
template <typename T = int>
struct notify_all_t
{
notify_all_t() noexcept = default;
notify_all_t(T& cpu) noexcept
{
vm::temporary_unlock(cpu);
cpu_counter::remove(&cpu);
}
~notify_all_t() noexcept
{
if constexpr (!std::is_base_of_v<cpu_thread, T>)
{
if (auto cpu = cpu_thread::get_current(); cpu && cpu->is_paused())
{
vm::temporary_unlock(*cpu);
}
}
lv2_obj::notify_all();
}
};