Skip to content

Commit

Permalink
IDM: Implement lock-free smart pointers
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Dec 22, 2024
1 parent 3857106 commit 8a6fe0d
Show file tree
Hide file tree
Showing 124 changed files with 1,143 additions and 1,052 deletions.
6 changes: 3 additions & 3 deletions Utilities/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,7 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
// check if address is RawSPU MMIO register
do if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET)
{
auto thread = idm::get<named_thread<spu_thread>>(spu_thread::find_raw_spu((addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET));
auto thread = idm::get_unlocked<named_thread<spu_thread>>(spu_thread::find_raw_spu((addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET));

if (!thread)
{
Expand Down Expand Up @@ -1548,7 +1548,7 @@ bool handle_access_violation(u32 addr, bool is_writing, ucontext_t* context) noe
}
}

if (auto pf_port = idm::get<lv2_obj, lv2_event_port>(pf_port_id); pf_port && pf_port->queue)
if (auto pf_port = idm::get_unlocked<lv2_obj, lv2_event_port>(pf_port_id); pf_port && pf_port->queue)
{
// We notify the game that a page fault occurred so it can rectify it.
// Note, for data3, were the memory readable AND we got a page fault, it must be due to a write violation since reads are allowed.
Expand Down Expand Up @@ -2602,7 +2602,7 @@ bool thread_base::join(bool dtor) const

if (i >= 16 && !(i & (i - 1)) && timeout != atomic_wait_timeout::inf)
{
sig_log.error(u8"Thread [%s] is too sleepy. Waiting for it %.3fµs already!", *m_tname.load(), (utils::get_tsc() - stamp0) / (utils::get_tsc_freq() / 1000000.));
sig_log.error(u8"Thread [%s] is too sleepy. Waiting for it %.3fus already!", *m_tname.load(), (utils::get_tsc() - stamp0) / (utils::get_tsc_freq() / 1000000.));
}
}

Expand Down
2 changes: 1 addition & 1 deletion Utilities/mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class shared_mutex final

void unlock_hle()
{
const u32 value = atomic_storage<u32>::fetch_add_hle_rel(m_value.raw(), 0u - c_one);
const u32 value = atomic_storage<u32>::fetch_add_hle_rel(m_value.raw(), ~c_one + 1);

if (value != c_one) [[unlikely]]
{
Expand Down
5 changes: 3 additions & 2 deletions rpcs3/Emu/CPU/CPUDisAsm.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <string>
#include "Emu/CPU/CPUThread.h"
#include "Utilities/StrFmt.h"

enum class cpu_disasm_mode
Expand All @@ -22,7 +23,7 @@ class CPUDisAsm
const u8* m_offset{};
const u32 m_start_pc;
std::add_pointer_t<const cpu_thread> m_cpu{};
std::shared_ptr<cpu_thread> m_cpu_handle;
shared_ptr<cpu_thread> m_cpu_handle;
u32 m_op = 0;

void format_by_mode()
Expand Down Expand Up @@ -81,7 +82,7 @@ class CPUDisAsm
return const_cast<cpu_thread*>(m_cpu);
}

void set_cpu_handle(std::shared_ptr<cpu_thread> cpu)
void set_cpu_handle(shared_ptr<cpu_thread> cpu)
{
m_cpu_handle = std::move(cpu);

Expand Down
28 changes: 14 additions & 14 deletions rpcs3/Emu/CPU/CPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void fmt_class_string<cpu_threads_emulation_info_dump_t>::format(std::string& ou
const u32 must_have_cpu_id = static_cast<u32>(arg);

// Dump main_thread
const auto main_ppu = idm::get<named_thread<ppu_thread>>(ppu_thread::id_base);
const auto main_ppu = idm::get_unlocked<named_thread<ppu_thread>>(ppu_thread::id_base);

if (main_ppu)
{
Expand All @@ -99,7 +99,7 @@ void fmt_class_string<cpu_threads_emulation_info_dump_t>::format(std::string& ou
{
if (must_have_cpu_id != ppu_thread::id_base)
{
const auto selected_ppu = idm::get<named_thread<ppu_thread>>(must_have_cpu_id);
const auto selected_ppu = idm::get_unlocked<named_thread<ppu_thread>>(must_have_cpu_id);

if (selected_ppu)
{
Expand All @@ -110,7 +110,7 @@ void fmt_class_string<cpu_threads_emulation_info_dump_t>::format(std::string& ou
}
else if (must_have_cpu_id >> 24 == spu_thread::id_base >> 24)
{
const auto selected_spu = idm::get<named_thread<spu_thread>>(must_have_cpu_id);
const auto selected_spu = idm::get_unlocked<named_thread<spu_thread>>(must_have_cpu_id);

if (selected_spu)
{
Expand Down Expand Up @@ -236,7 +236,7 @@ struct cpu_prof
}

// Print info
void print(const std::shared_ptr<cpu_thread>& ptr)
void print(const shared_ptr<cpu_thread>& ptr)
{
if (new_samples < min_print_samples || samples == idle)
{
Expand All @@ -263,7 +263,7 @@ struct cpu_prof
new_samples = 0;
}

static void print_all(std::unordered_map<std::shared_ptr<cpu_thread>, sample_info>& threads, sample_info& all_info)
static void print_all(std::unordered_map<shared_ptr<cpu_thread>, sample_info>& threads, sample_info& all_info)
{
u64 new_samples = 0;

Expand Down Expand Up @@ -319,7 +319,7 @@ struct cpu_prof

void operator()()
{
std::unordered_map<std::shared_ptr<cpu_thread>, sample_info> threads;
std::unordered_map<shared_ptr<cpu_thread>, sample_info> threads;

while (thread_ctrl::state() != thread_state::aborting)
{
Expand All @@ -335,15 +335,15 @@ struct cpu_prof
continue;
}

std::shared_ptr<cpu_thread> ptr;
shared_ptr<cpu_thread> ptr;

if (id >> 24 == 1)
{
ptr = idm::get<named_thread<ppu_thread>>(id);
ptr = idm::get_unlocked<named_thread<ppu_thread>>(id);
}
else if (id >> 24 == 2)
{
ptr = idm::get<named_thread<spu_thread>>(id);
ptr = idm::get_unlocked<named_thread<spu_thread>>(id);
}
else
{
Expand Down Expand Up @@ -437,7 +437,7 @@ struct cpu_prof
continue;
}

// Wait, roughly for 20µs
// Wait, roughly for 20us
thread_ctrl::wait_for(20, false);
}

Expand Down Expand Up @@ -1302,7 +1302,7 @@ cpu_thread* cpu_thread::get_next_cpu()
return nullptr;
}

std::shared_ptr<CPUDisAsm> make_disasm(const cpu_thread* cpu, std::shared_ptr<cpu_thread> handle);
std::shared_ptr<CPUDisAsm> make_disasm(const cpu_thread* cpu, shared_ptr<cpu_thread> handle);

void cpu_thread::dump_all(std::string& ret) const
{
Expand All @@ -1318,7 +1318,7 @@ void cpu_thread::dump_all(std::string& ret) const
if (u32 cur_pc = get_pc(); cur_pc != umax)
{
// Dump a snippet of currently executed code (may be unreliable with non-static-interpreter decoders)
auto disasm = make_disasm(this, nullptr);
auto disasm = make_disasm(this, null_ptr);

const auto rsx = try_get<rsx::thread>();

Expand Down Expand Up @@ -1558,14 +1558,14 @@ u32 CPUDisAsm::DisAsmBranchTarget(s32 /*imm*/)
return 0;
}

extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool revert_lock, std::vector<std::pair<std::shared_ptr<named_thread<spu_thread>>, u32>>* out_list)
extern bool try_lock_spu_threads_in_a_state_compatible_with_savestates(bool revert_lock, std::vector<std::pair<shared_ptr<named_thread<spu_thread>>, u32>>* out_list)
{
if (out_list)
{
out_list->clear();
}

auto get_spus = [old_counter = u64{umax}, spu_list = std::vector<std::shared_ptr<named_thread<spu_thread>>>()](bool can_collect, bool force_collect) mutable
auto get_spus = [old_counter = u64{umax}, spu_list = std::vector<shared_ptr<named_thread<spu_thread>>>()](bool can_collect, bool force_collect) mutable
{
const u64 new_counter = cpu_thread::g_threads_created + cpu_thread::g_threads_deleted;

Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/Modules/cellAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ void cell_audio_thread::advance(u64 timestamp)
m_dynamic_period = 0;

// send aftermix event (normal audio event)
std::array<std::shared_ptr<lv2_event_queue>, MAX_AUDIO_EVENT_QUEUES> queues;
std::array<shared_ptr<lv2_event_queue>, MAX_AUDIO_EVENT_QUEUES> queues;
u32 queue_count = 0;

event_period++;
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/Modules/cellAudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ class cell_audio_thread
u32 flags = 0; // iFlags
u64 source = 0; // Event source
u64 ack_timestamp = 0; // timestamp of last call of cellAudioSendAck
std::shared_ptr<lv2_event_queue> port{}; // Underlying event port
shared_ptr<lv2_event_queue> port{}; // Underlying event port
};

std::vector<key_info> keys{};
Expand Down
26 changes: 13 additions & 13 deletions rpcs3/Emu/Cell/Modules/cellDmux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1031,7 +1031,7 @@ error_code cellDmuxClose(u32 handle)
{
cellDmux.warning("cellDmuxClose(handle=0x%x)", handle);

const auto dmux = idm::get<Demuxer>(handle);
const auto dmux = idm::get_unlocked<Demuxer>(handle);

if (!dmux)
{
Expand Down Expand Up @@ -1060,7 +1060,7 @@ error_code cellDmuxSetStream(u32 handle, u32 streamAddress, u32 streamSize, b8 d
{
cellDmux.trace("cellDmuxSetStream(handle=0x%x, streamAddress=0x%x, streamSize=%d, discontinuity=%d, userData=0x%llx)", handle, streamAddress, streamSize, discontinuity, userData);

const auto dmux = idm::get<Demuxer>(handle);
const auto dmux = idm::get_unlocked<Demuxer>(handle);

if (!dmux)
{
Expand Down Expand Up @@ -1088,7 +1088,7 @@ error_code cellDmuxResetStream(u32 handle)
{
cellDmux.warning("cellDmuxResetStream(handle=0x%x)", handle);

const auto dmux = idm::get<Demuxer>(handle);
const auto dmux = idm::get_unlocked<Demuxer>(handle);

if (!dmux)
{
Expand All @@ -1103,7 +1103,7 @@ error_code cellDmuxResetStreamAndWaitDone(u32 handle)
{
cellDmux.warning("cellDmuxResetStreamAndWaitDone(handle=0x%x)", handle);

const auto dmux = idm::get<Demuxer>(handle);
const auto dmux = idm::get_unlocked<Demuxer>(handle);

if (!dmux)
{
Expand Down Expand Up @@ -1164,7 +1164,7 @@ error_code cellDmuxEnableEs(u32 handle, vm::cptr<CellCodecEsFilterId> esFilterId
{
cellDmux.warning("cellDmuxEnableEs(handle=0x%x, esFilterId=*0x%x, esResourceInfo=*0x%x, esCb=*0x%x, esSpecificInfo=*0x%x, esHandle=*0x%x)", handle, esFilterId, esResourceInfo, esCb, esSpecificInfo, esHandle);

const auto dmux = idm::get<Demuxer>(handle);
const auto dmux = idm::get_unlocked<Demuxer>(handle);

if (!dmux)
{
Expand Down Expand Up @@ -1194,7 +1194,7 @@ error_code cellDmuxDisableEs(u32 esHandle)
{
cellDmux.warning("cellDmuxDisableEs(esHandle=0x%x)", esHandle);

const auto es = idm::get<ElementaryStream>(esHandle);
const auto es = idm::get_unlocked<ElementaryStream>(esHandle);

if (!es)
{
Expand All @@ -1213,7 +1213,7 @@ error_code cellDmuxResetEs(u32 esHandle)
{
cellDmux.trace("cellDmuxResetEs(esHandle=0x%x)", esHandle);

const auto es = idm::get<ElementaryStream>(esHandle);
const auto es = idm::get_unlocked<ElementaryStream>(esHandle);

if (!es)
{
Expand All @@ -1232,7 +1232,7 @@ error_code cellDmuxGetAu(u32 esHandle, vm::ptr<u32> auInfo, vm::ptr<u32> auSpeci
{
cellDmux.trace("cellDmuxGetAu(esHandle=0x%x, auInfo=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfo, auSpecificInfo);

const auto es = idm::get<ElementaryStream>(esHandle);
const auto es = idm::get_unlocked<ElementaryStream>(esHandle);

if (!es)
{
Expand All @@ -1255,7 +1255,7 @@ error_code cellDmuxPeekAu(u32 esHandle, vm::ptr<u32> auInfo, vm::ptr<u32> auSpec
{
cellDmux.trace("cellDmuxPeekAu(esHandle=0x%x, auInfo=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfo, auSpecificInfo);

const auto es = idm::get<ElementaryStream>(esHandle);
const auto es = idm::get_unlocked<ElementaryStream>(esHandle);

if (!es)
{
Expand All @@ -1278,7 +1278,7 @@ error_code cellDmuxGetAuEx(u32 esHandle, vm::ptr<u32> auInfoEx, vm::ptr<u32> auS
{
cellDmux.trace("cellDmuxGetAuEx(esHandle=0x%x, auInfoEx=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfoEx, auSpecificInfo);

const auto es = idm::get<ElementaryStream>(esHandle);
const auto es = idm::get_unlocked<ElementaryStream>(esHandle);

if (!es)
{
Expand All @@ -1301,7 +1301,7 @@ error_code cellDmuxPeekAuEx(u32 esHandle, vm::ptr<u32> auInfoEx, vm::ptr<u32> au
{
cellDmux.trace("cellDmuxPeekAuEx(esHandle=0x%x, auInfoEx=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfoEx, auSpecificInfo);

const auto es = idm::get<ElementaryStream>(esHandle);
const auto es = idm::get_unlocked<ElementaryStream>(esHandle);

if (!es)
{
Expand All @@ -1324,7 +1324,7 @@ error_code cellDmuxReleaseAu(u32 esHandle)
{
cellDmux.trace("cellDmuxReleaseAu(esHandle=0x%x)", esHandle);

const auto es = idm::get<ElementaryStream>(esHandle);
const auto es = idm::get_unlocked<ElementaryStream>(esHandle);

if (!es)
{
Expand All @@ -1342,7 +1342,7 @@ error_code cellDmuxFlushEs(u32 esHandle)
{
cellDmux.warning("cellDmuxFlushEs(esHandle=0x%x)", esHandle);

const auto es = idm::get<ElementaryStream>(esHandle);
const auto es = idm::get_unlocked<ElementaryStream>(esHandle);

if (!es)
{
Expand Down
Loading

0 comments on commit 8a6fe0d

Please sign in to comment.